From b9ba4da985c644e6c2f8a37948c5d1c360b50f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?16=20=E9=98=99=E8=8B=8F=E6=96=87?= <2361635242@qq.com> Date: Mon, 16 Oct 2023 20:49:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...27\345\217\243\345\207\275\346\225\260.md" | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 "16 \351\230\231\350\213\217\346\226\207/20231016.\347\252\227\345\217\243\345\207\275\346\225\260.md" diff --git "a/16 \351\230\231\350\213\217\346\226\207/20231016.\347\252\227\345\217\243\345\207\275\346\225\260.md" "b/16 \351\230\231\350\213\217\346\226\207/20231016.\347\252\227\345\217\243\345\207\275\346\225\260.md" new file mode 100644 index 0000000..ab26003 --- /dev/null +++ "b/16 \351\230\231\350\213\217\346\226\207/20231016.\347\252\227\345\217\243\345\207\275\346\225\260.md" @@ -0,0 +1,123 @@ +# 笔记 + +## 窗口函数 + +mysql 8.0新增窗口函数(开窗函数) + +非聚合窗口函数:是相对于聚合函数来说的,特性为非聚合。一次只处理一行数据。 + +窗口聚合函数:窗口聚合函数在单元行上计算某个字段的结果时,可将窗口范围内的数据输入到聚合函数中,并且不会改变行数。 + +语法: + +窗口函数名称(参数) over(partition by ... order by... 窗口大小) + +partition by 分组,等价于group by order by 排序 + +### 序号函数 + +row_number()、rank()、dense_rank() + + + +### 分布函数 + +##### cume_dist() + +分组内 <= 或 >= 当前值的行数占比(包含当前值本身) + +### 前后函数 + +返回当前行的前某一行的值,或者后某一行的值 + +lag(列名,前第n行) + +lead(列名,后第n行) + +### 头尾函数 + +返回第一个或最后一个列的值 + +first_value(列名) + +last_value(列名) + +### 其他函数 + +nth_value(列名,n) —— 返回截止到当前行,该列的第n个值 + +# 作业 + +```mysql +### -- 窗口函数 + +#求每个部门的员工总数 +select distinct dname,count(eid) over (partition by dname) from employee; + +#求每个部门的平均工资 +select distinct dname,avg(salary) over (partition by dname) from employee; + +#求每个部门的工资排名(从高到低,相同工资并列,并执行跳过排序) +select dname,ename,salary,rank() over (order by salary desc) from employee; + +#求公司所有员工的年龄排序(相同年龄并列,执行跳过排序) +select ename,birth,datediff(now(),birth) div 365 ,rank() over (order by datediff(now(),birth) div 365 desc) from employee; + +#求每个部门的员工工龄排序(相同年龄并列,执行顺序排序) +select ename,hiredate,datediff(now(),hiredate) div 365 ,rank() over (order by datediff(now(),hiredate) div 365 desc) from employee; + +#计算每个员工的工资与该部门平均工资的差额 +select dname,ename,(salary-avg(salary) over (partition by dname)) from employee; + +#按员工工资进行排序,比较相邻两个员工的工资,输出比较高的工资 +select ename,salary,max(salary) over (rows between 1 preceding and 1 following) from employee; + +#按员工工资进行排序,查询当前员工与前一位和后一位的工资平均值 +select ename,salary,avg(salary) over (rows between 1 preceding and 1 following) from employee; + +#按员工工资进行排序,查询当前员工至最后一位员工的工资总和 +select ename,sum(salary) over (rows between current row and unbounded following) from employee; + +#计算每个部门内最高薪资与平均薪资的差额 +select distinct dname,max(salary) over (partition by dname)-avg(salary) over (partition by dname) from employee; + +#找出各部门年薪第二高的员工 +select * from (select dname,eid,ename,salary,dense_rank() over (partition by dname order by salary desc) 排序 from employee) a where 排序=2; + +#查询各部门中小于等于当前员工实际薪资的比例 +select dname,ename,salary,cume_dist() over (partition by dname order by salary asc) from employee; + +#查询每个员工工资在全部员工中的排名比例 +select ename,salary,cume_dist() over (order by salary) from employee; from employee; + +#查询每个部门工资排名在前25%的员工记录数 +select * from (select *,ntile(4) over (partition by dname order by salary desc) a from employee) b where a=1; + +#每个部门按年龄进行排序,求当前员工与前一位员工的年龄差 +select dname,ename,birth,datediff(birth,lag(birth) over (partition by dname order by birth)) from employee; +#按入职日期进行排序,查询公司每个员工与后面一个员工的入职天数差异 + +#将每个部门的员工按工资平均分为2个组,组1为低工资,组2为高工资 +select dname,ename,salary,ntile(2) over (partition by dname order by salary) from employee; + +#将所有员工按照工龄分为4个组,并统计每个组的人数 +select b.a,count(b.a) from (select dname,ename,ntile(4) over (order by birth) a from employee) b group by b.a; + +#将员工按照工资分为3个组,并统计组别,每组平均工资,工资范围(first_value、last_value) +select num,avg(salary),min(salary),max(salary) from (select *,ntile(3) over (order by salary) num from employee) b group by num; + +### -- 非窗口函数 + +#按照工龄区分等级,小于5年为新员工,5-15年为老员工,大于15年为骨灰级员工,输出姓名,部门,工龄,级别 +select ename,dname,hiredate,floor(datediff(curdate(),hiredate)/365),case when floor(datediff(curdate(),hiredate)/365)<5 then '新员工' when floor(datediff(curdate(),hiredate)/365)>15 then '老员工' else '骨灰级员工' end '员工判定' from employee; + +#返回员工的实际年龄,如果小于当前日期则减1岁 +select ename,dname,birth,floor(datediff(curdate(),birth)/365)-case when date_format(curdate(),'%m%d')