SQL62 出现三次以上相同积分的情况
SELECT number FROM grade GROUP BY number HAVING COUNT(id) >= 3;
SQL63 刷题通过的题目排名
注意:题干说了相同题目数的排名并列,另外从结果表中可以看到名次有并列但连续无跳过,所以是中式排名求 "档次",所以窗口函数法要用 DENSE_RANK(),子查询法要用 DISTINCT
法1. 窗口函数法
SELECT id, number, DENSE_RANK() OVER(ORDER BY number DESC) AS t_rank FROM passing_number ORDER BY t_rank;
法2. 子查询法
SELECT *, ( SELECT count(DISTINCT number) FROM passing_number WHERE number>=pr.number ) FROM passing_number pr ORDER BY number DESC
SQL64 找到每个人的任务
SELECT p.id, name, content FROM person p LEFT JOIN task t ON p.id = t.person_id ORDER BY id;
SQL65 异常的邮件概率
写一个sql查询,每一个日期里面,正常用户发送给正常用户邮件失败的概率是多少,结果保留到小数点后面3位(3位之后的四舍五入),并且按照日期升序排序
(注意: sqlite 1/2得到的不是0.5,得到的是0,只有1*1.0/2才会得到0.5(MySQL 没有这个问题),sqlite四舍五入的函数为round)
SELECT date, round( sum(case type when'completed' then 0 else 1 end)/count(type),3 ) FROM email e JOIN user u1 ON e.send_id=u1.id AND u1.is_blacklist=0 JOIN user u2 ON e.receive_id=u2.id AND u2.is_blacklist=0 GROUP BY date ORDER BY date
SQL66 牛客每个人最近的登录日期(一)
写出一个sql语句查询每个用户最近一天登录的日子,并且按照user_id升序排序
SELECT user_id, MAX(date) d FROM login GROUP BY user_id ORDER BY user_id
SQL67 牛客每个人最近的登录日期(二)
写出一个sql语句查询每个用户最近一天登录的日子,用户的名字,以及用户用的设备的名字,并且查询结果按照user的name升序排序
思路:
上一个题求的是各用户的最晚登陆日期,直接 GROUP BY user_id 然后求 MAX(date) 即可
但这个题不一样,它还要求得到个每个用户最后一次登录所使用的设备,所以不能直接分组统计(分组统计的结果中不能包含除了分组依据和聚合函数以外的字段(如这里的 "设备"))
相反,应该在 WHERE 中用关联子查询获得每个用户的最晚登陆日期来对原表进行筛选,这样在结果中就能包含 "设备" 字段了
法1:子查询
SELECT u.name u_n, c.name c_n, date FROM login l JOIN user u ON l.user_id=u.id JOIN client c ON l.client_id=c.id WHERE date=( SELECT MAX(date) FROM login WHERE user_id=l.user_id) ORDER BY u_n
法2:窗口函数
select u.name as u_n, c.name as c_n, temp.date from ( select user_id, client_id, date, MAX(date) over (partition by user_id) as date2 from login ) as temp join client as c on c.id = temp.client_id join user u on temp.user_id = u.id where temp.date2 = date order by u.name