常用难sql总结一

常见sql总结一

知识点 描述 题号
datediff 对日期类型做比较 1
3+表联表查询 层级递进慢慢写 2
replace函数 replace(字段名,value1,value2) 3
rank() over (order by xxx desc) rank并列并舍弃 4
row_number() 继续排序 4
dense_rank() 并列不舍弃 4
partition by xxx 多次重新排序 5
limit m,n 其中m是指记录开始的index,从0开始,表示第一条记录;n是指从m+1条开始,取n条。 6

1、牛客每个人最近的登录日期(五)

描述

牛客每天有很多人登录,请你统计一下牛客每个日期新用户的次日留存率。
有一个登录(login)记录表,简况如下:

id user_id client_id date
1 2 1 2020-10-12
2 3 2 2020-10-12
3 1 2 2020-10-12
4 2 2 2020-10-13
5 1 2 2020-10-13
6 3 1 2020-10-14
7 4 1 2020-10-14
8 4 1 2020-10-15

请你写出一个sql语句查询每个日期新用户的次日留存率,结果保留小数点后面3位数(3位之后的四舍五入),并且查询结果按照日期升序排序,上面的例子查询结果如下:

date p
2020-10-12 0.667
2020-10-13 0.000
2020-10-14 1.000
2020-10-15 0.000

查询结果表明:
2020-10-12登录了3个(user_id为2,3,1)新用户,2020-10-13,只有2个(id为2,1)登录,故2020-10-12新用户次日留存率为2/3=0.667;
2020-10-13没有新用户登录,输出0.000;
2020-10-14登录了1个(user_id为4)新用户,2020-10-15,user_id为4的用户登录,故2020-10-14新用户次日留存率为1/1=1.000;

2020-10-15没有新用户登录,输出0.000;

(注意:sqlite里查找某一天的后一天的用法是:date(yyyy-mm-dd, ‘+1 day’),sqlite里1/2得到的不是0.5,得到的是0,只有1*1.0/2才会得到0.5)

SELECT date,IFNULL(ROUND(SUM(CASE WHEN (user_id,date) IN
(SELECT user_id,DATE_ADD(date,INTERVAL -1 DAY) FROM login)
AND (user_id,date) IN (SELECT user_id,MIN(date) FROM login GROUP BY user_id)
THEN 1 ELSE 0 END)/
SUM(CASE WHEN (user_id,date) IN (SELECT user_id,MIN(date) FROM login GROUP BY user_id)
THEN 1 ELSE 0 END),3),0) AS p
FROM login
GROUP BY date
ORDER BY date;

2、获取员工其当前的薪水比其manager当前薪水还高的相关信息

描述

有一个,部门关系表dept_emp简况如下:

emp_no dept_no from_date to_date
10001 d001 1986-06-26 9999-01-01
10002 d001 1996-08-03 9999-01-01

有一个部门经理表dept_manager简况如下:

dept_no emp_no from_date to_date
d001 10002 1996-08-03 9999-01-01

有一个薪水表salaries简况如下:

emp_no salary from_date to_date
10001 88958 2002-06-22 9999-01-01
10002 72527 1996-08-03 9999-01-01

获取员工其当前的薪水比其manager当前薪水还高的相关信息,

第一列给出员工的emp_no,
第二列给出其manager的manager_no,
第三列给出该员工当前的薪水emp_salary,
第四列给该员工对应的manager当前的薪水manager_salary

以上例子输出如下:

emp_no manager_no emp_salary manager_salary
10001 10002 88958 72527
select
    a.emp_no,
    b.emp_no as manager_no,
    c.salary as emp_salary,
    d.salary as manager_dalary
from
    dept_emp a
    left join dept_manager b on a.dept_no = b.dept_no
    left join salaries c on a.emp_no = c.emp_no
    left join salaries d on b.emp_no = d.emp_no
having
    c.salary > d.salary

3、将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005,其他数据保持不变,使用replace实现要求

UPDATE
    titles_test
set
    emp_no = REPLACE (emp_no, "10001", "10005");

4、获取当前薪水第二多的员工的emp_no以及其对应的薪水sal

链接:https://www.nowcoder.com/questionTerminal/8d2c290cc4e24403b98ca82ce45d04db
来源:牛客网

有一个薪水表salaries简况如下:

emp_no salary from_date to_date
10001 88958 2002-06-22 9999-01-01
10002 72527 2001-08-02 9999-01-01
10003 43311 2001-12-01 9999-01-01

请你获取薪水第二多的员工的emp_no以及其对应的薪水salary,

若有多个员工的薪水为第二多的薪水,则将对应的员工的emp_no和salary全部输出,并按emp_no升序排序。

emp_no salary
10002 72527
select
    emp_no,
    salary
from
    (
        select
            emp_no,
            salary,
            rank() over (
                order by
                    salary desc
            ) as t_rank
        from
            salaries
    ) as T
where
    T.t_rank = 2

5、获取每个部门中当前员工薪水最高的相关信息

描述

有一个员工表dept_emp简况如下:

emp_no dept_no from_date to_date
10001 d001 1986-06-26 9999-01-01
10002 d001 1996-08-03 9999-01-01
10003 d002 1996-08-03 9999-01-01

有一个薪水表salaries简况如下:

emp_no salary from_date to_date
10001 88958 2002-06-22 9999-01-01
10002 72527 2001-08-02 9999-01-01
10003 92527 2001-08-02 9999-01-01

获取每个部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary,按照部门编号dept_no升序排列,以上例子输出如下:

dept_no emp_no maxSalary
d001 10001 88958
d002 10003 92527
select
    dept_no,
    emp_no,
    salary as maxSalary
from
    (
        select
            a.dept_no,
            a.emp_no,
            b.salary,
            row_number() over (
                partition by
                    a.dept_no
                order by
                    salary desc
            ) as tmp_no
        from
            dept_emp a
            left join salaries b on a.emp_no = b.emp_no
    ) as T
where
    T.tmp_no = 1

6、查找入职员工时间排名倒数第三的员工所有信息

要求可能有并列的存在

select
    *
from
    employees
where
    hire_date = (
        select
            hire_date
        from
            employees
        group by
            hire_date
        order by
            hire_date desc
        limit
            2, 1
    )

你可能感兴趣的:(sql,数据库,sqlite)