diff --git "a/39 \351\203\255\346\202\246\350\277\216/20231017 \344\275\234\344\270\232\345\244\215\344\271\240.md" "b/39 \351\203\255\346\202\246\350\277\216/20231017 \344\275\234\344\270\232\345\244\215\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..5bc3dbe9da72cce348376616950762458322c27d --- /dev/null +++ "b/39 \351\203\255\346\202\246\350\277\216/20231017 \344\275\234\344\270\232\345\244\215\344\271\240.md" @@ -0,0 +1,189 @@ +## 笔记 + +timestampdiff():是mysql中用来计算两个日期或时间之间的差值的函数,该函数返回两个日期/时间之间的差值,可以指定差值的单位(秒、分钟、小时、天等) + +```mysql +语法: +timestampdiff( unit,start_date,end_date); +-- unit : 表示差值的单位,可以是一下值之一:microsecond(微秒),second(秒),minute(分)。。。 +-- start_date : 表示时间段的起始时间 +-- end_date : 表示时间段的结束时间 +``` + + + +## 作业 + +```mysql +create database db_emp charset utf8; +use db_emp; +create table if not exists `employee` +( + `eid` int not null auto_increment comment '员工id' primary key, + `ename` varchar(20) not null comment '员工名称', + `dname` varchar(50) not null comment '部门名称', + `hiredate` datetime not null comment '入职日期', + `birth` date not null comment '生日', + `salary` double null comment '基本薪资', + `start_sal` double null comment '入职薪资' +); + +insert into `employee` (`ename`, `dname`, `hiredate`,`birth`, `salary`,`start_sal`) values ('傅嘉熙', '开发部', '2002-08-20 12:00:04','1980-12-10', 9000,6500); +insert into `employee` (`ename`, `dname`, `hiredate`, `birth`,`salary`,`start_sal`) values ('武晟睿', '开发部', '2002-06-12 13:54:12', '1984-2-5',9500,6000); +insert into `employee` (`ename`, `dname`, `hiredate`, `birth`,`salary`,`start_sal`) values ('孙弘文', '开发部', '2003-10-16 08:27:06','1979-8-7', 9400,8000); +insert into `employee` (`ename`, `dname`, `hiredate`,`birth`, `salary`,`start_sal`) values ('潘乐驹', '开发部', '2004-04-22 03:56:11','1980-5-12', 9500,6800); +insert into `employee` (`ename`, `dname`, `hiredate`,`birth`, `salary`,`start_sal`) values ('潘昊焱', '人事部', '2007-02-24 03:40:02','1987-2-12', 5000,4500); +insert into `employee` (`ename`, `dname`, `hiredate`,`birth`, `salary`,`start_sal`) values ('沈涛', '人事部', '2012-12-14 09:16:37','1993-4-30', 6000,5500); +insert into `employee` (`ename`, `dname`, `hiredate`, `birth`,`salary`,`start_sal`) values ('江峻熙', '人事部', '2018-05-12 01:17:48','1990-6-8', 5000,3000); +insert into `employee` (`ename`, `dname`, `hiredate`,`birth`, `salary`,`start_sal`) values ('陆远航', '人事部', '2018-04-14 03:35:57','1989-11-13', 5500,5000); +insert into `employee` (`ename`, `dname`, `hiredate`, `birth`,`salary`,`start_sal`) values ('姜煜祺', '销售部', '2020-03-23 03:21:05','1995-1-1', 6000,5500); +insert into `employee` (`ename`, `dname`, `hiredate`, `birth`,`salary`,`start_sal`) values ('邹明', '销售部', '2015-11-23 23:10:06','1996-2-19', 6800,6000); +insert into `employee` (`ename`, `dname`, `hiredate`, `birth`,`salary`,`start_sal`) values ('董擎苍', '销售部', '2012-02-12 07:54:32','1985-10-7', 6500,4800); +insert into `employee` (`ename`, `dname`, `hiredate`,`birth`, `salary`,`start_sal`) values ('钟俊驰', '销售部', '2010-04-10 12:17:06','1981-3-25', 6000,3500); + +-- 员工按工龄,每年增加50元薪水。实发薪资 = 基本薪资 + 工龄 * 50 +### -- 窗口函数 +#求每个部门的员工总数 + select distinct dname 部门编号,count(*) over (partition by dname order by dname) '员工总数' from employee ; +#求每个部门的平均工资 + select distinct dname 部门编号,AVG(salary) over (partition by dname) '平均工资' from employee; +#求每个部门的工资排名(从高到低,相同工资并列,并执行跳过排序) + select RANK() over (partition by dname order by salary desc) as dname,salary from employee; +#求公司所有员工的年龄排序(相同年龄并列,执行跳过排序) + select RANK() over (partition by dname order by birth) as ename,birth from employee; +#求每个部门的员工工龄排序(相同年龄并列,执行顺序排序) + select ROW_NUMBER() over (partition by dname order by hiredate) as ename,hiredate from employee; +#计算每个员工的工资与该部门平均工资的差额 + SELECT eid, ename, dname, salary, AVG(salary) OVER (PARTITION BY dname) - salary AS 差额 FROM employee; +#按员工工资进行排序,比较相邻两个员工的工资,输出比较高的工资 +SELECT ename, salary, + CASE + WHEN LAG(salary) OVER (ORDER BY salary) > salary THEN LAG(salary) OVER (ORDER BY salary) + ELSE salary + END AS 比较高的工资 +FROM employee +ORDER BY salary; +#按员工工资进行排序,查询当前员工与前一位和后一位的工资平均值 +SELECT ename, salary, + (LAG(salary) OVER (ORDER BY salary) + salary + LEAD(salary) OVER (ORDER BY salary)) / 3 AS 平均工资 +FROM employee +ORDER BY salary; +#按员工工资进行排序,查询当前员工至最后一位员工的工资总和 +SELECT ename, salary, + SUM(salary) OVER (ORDER BY salary DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS 工资总和 +FROM employee +ORDER BY salary; +#计算每个部门内最高薪资与平均薪资的差额 +SELECT dname, MAX(salary) - AVG(salary) AS 薪资差额 +FROM employee +GROUP BY dname; +#找出各部门年薪第二高的员工 +SELECT dname, ename, salary +FROM ( + SELECT dname, ename, salary, + ROW_NUMBER() OVER (PARTITION BY dname ORDER BY salary DESC) AS rn + FROM employee +) tmp +WHERE rn = 2; +#查询各部门中小于等于当前员工实际薪资的比例 +SELECT +e.dname, +COUNT() / (SELECT COUNT() FROM employee WHERE dname = e.dname) AS ratio +FROM +employee e +WHERE +e.salary <= (SELECT salary FROM employee WHERE ename = ‘傅嘉熙’) +GROUP BY +e.dname; +#查询每个员工工资在全部员工中的排名比例 +SELECT +e.ename, +COUNT() / (SELECT COUNT() FROM employee) AS ratio +FROM +employee e +WHERE +e.salary <= (SELECT salary FROM employee WHERE ename = ‘傅嘉熙’) +GROUP BY +e.ename; + +#查询每个部门工资排名在前25%的员工记录数 +SELECT +e.dname, +COUNT() AS count +FROM +employee e +WHERE +(SELECT COUNT() FROM employee WHERE dname = e.dname AND salary <= e.salary) <= (SELECT COUNT(*) FROM employee WHERE dname = e.dname) * 0.25 +GROUP BY +e.dname; + +#每个部门按年龄进行排序,求当前员工与前一位员工的年龄差 +SELECT +e.dname, +e.ename, +e.birth, +ABS(e.birth - (SELECT birth FROM employee WHERE dname = e.dname AND birth < e.birth ORDER BY birth DESC LIMIT 1)) AS age_difference +FROM +employee e +ORDER BY +e.dname, +e.birth; +#按入职日期进行排序,查询公司每个员工与后面一个员工的入职天数差异 +SELECT +e.ename, +e.hiredate, +DATEDIFF((SELECT hiredate FROM employee WHERE hiredate > e.hiredate ORDER BY hiredate ASC LIMIT 1), e.hiredate) AS day_difference +FROM +employee e +ORDER BY +e.hiredate; +#将每个部门的员工按工资平均分为2个组,组1为低工资,组2为高工资 +SELECT +e.dname, +CASE WHEN e.salary <= (SELECT AVG(salary) FROM employee WHERE dname = e.dname) THEN ‘低工资’ ELSE ‘高工资’ END AS salary_group +FROM +employee e +ORDER BY +e.dname; +#将所有员工按照工龄分为4个组,并统计每个组的人数 +SELECT +CASE +WHEN YEAR(CURDATE()) - YEAR(e.hiredate) < 5 THEN ‘0-4年’ +WHEN YEAR(CURDATE()) - YEAR(e.hiredate) < 10 THEN ‘5-9年’ +WHEN YEAR(CURDATE()) - YEAR(e.hiredate) < 15 THEN ‘10-14年’ +ELSE ‘15年以上’ +END AS work_experience_group, +COUNT(*) AS count +FROM +employee e +GROUP BY +work_experience_group; +#将员工按照工资分为3个组,并统计组别,每组平均工资,工资范围(first_value、last_value) +SELECT +CASE +WHEN salary <= (SELECT PERCENTILE_CONT(0.33) WITHIN GROUP (ORDER BY salary) FROM employee) THEN ‘低工资’ +WHEN salary <= (SELECT PERCENTILE_CONT(0.67) WITHIN GROUP (ORDER BY salary) FROM employee) THEN ‘中等工资’ +ELSE ‘高工资’ +END AS salary_group, +AVG(salary) AS average_salary, +MIN(salary) AS salary_range_start, +MAX(salary) AS salary_range_end +FROM +employee +GROUP BY +salary_group; + + +### -- 非窗口函数 + +#按照工龄区分等级,小于5年为新员工,5-15年为老员工,大于15年为骨灰级员工,输出姓名,部门,工龄,级别 + +#返回员工的实际年龄,如果小于当前日期则减1岁 + +#求每个员工还有多少天过生日,并返回下次生日是星期几 + +#求每个员工当前实发工资与入职时工资的增长率,输出员工姓名,部门,入职工资,实际工资,增长率 + + +``` +