「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」
描述
有一个薪水表,salaries简况如下:
请你查找薪水记录超过15次的员工号emp_no以及其对应的记录次数t,以上例子输出如下:
示例1
drop table if exists `salaries` ;
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
INSERT INTO salaries VALUES(10001,60117,'1986-06-26','1987-06-26');
INSERT INTO salaries VALUES(10001,62102,'1987-06-26','1988-06-25');
INSERT INTO salaries VALUES(10001,66074,'1988-06-25','1989-06-25');
INSERT INTO salaries VALUES(10001,66596,'1989-06-25','1990-06-25');
INSERT INTO salaries VALUES(10001,66961,'1990-06-25','1991-06-25');
INSERT INTO salaries VALUES(10001,71046,'1991-06-25','1992-06-24');
INSERT INTO salaries VALUES(10001,74333,'1992-06-24','1993-06-24');
INSERT INTO salaries VALUES(10001,75286,'1993-06-24','1994-06-24');
INSERT INTO salaries VALUES(10001,75994,'1994-06-24','1995-06-24');
INSERT INTO salaries VALUES(10001,76884,'1995-06-24','1996-06-23');
INSERT INTO salaries VALUES(10001,80013,'1996-06-23','1997-06-23');
INSERT INTO salaries VALUES(10001,81025,'1997-06-23','1998-06-23');
INSERT INTO salaries VALUES(10001,81097,'1998-06-23','1999-06-23');
INSERT INTO salaries VALUES(10001,84917,'1999-06-23','2000-06-22');
INSERT INTO salaries VALUES(10001,85112,'2000-06-22','2001-06-22');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','1997-08-03');
输出
10001|17
方法一
SELECT emp_no, COUNT(*) t
FROM salaries
GROUP BY emp_no
HAVING t > 15
按emp_no分组,统计分组的数量,返回数量大于15的信息;
方法二
SELECT *
FROM
(SELECT DISTINCT emp_no, COUNT(*) OVER(PARTITION BY emp_no) AS t FROM salaries) s1
WHERE t > 15
利用窗口函数,按emp_no分组,统计出各组的数量,并且利用emp_no去重,因为窗口函数,有多少结果,就会返回多少行,所以加上distinct关键字;
运行效果(方法一)
从上图我们可以看到,我们原先的语句变成了如下:
SELECT emp_no, COUNT(0) t
FROM salaries
GROUP BY emp_no
HAVING t > 15
COUNT(*)改成了COUNT(0);具体执行为:
对salaries表进行全表扫描,预计扫描的行数为18,开销为4.6,并且使用到了临时表;另外,排序用了开销18,总的开销为22.6;