MySQL中的窗口函数
MySQL窗口函数
其实,开窗函数是在 MySQL8.0 以后才新加的功能,因此,要想直接使用开窗函数,则 mysql 版本要 8.0 以上。其实开窗函数是在满足某种条件的记录集合上执行的特殊函数。对于每条记录都要在此窗口内执行函数,有的函数随着记录不同,窗口大小都是固定的,这种属于静态窗口;有的函数则相反,不同的记录对应着不同的窗口,这种动态变化的窗口叫滑动窗口。开窗函数的本质还是聚合运算,只不过它更具灵活性,它对数据的每一行,都使用与该行相关的行进行计算并返回计算结果。接下来,我们介绍开窗函数的相关语法;具体语法如下:
开窗函数名([<字段名>]) over([partition by <分组字段>] [order by <排序字段> [desc]] [< 细分窗口>])
- partition by 子句:按照指定字段进行分区,两个分区由边界分隔,开窗函数在不同的分区内分别执行,在跨越分区边界时重新初始化。
- order by 子句:按照指定字段进行排序,开窗函数将按照排序后的记录顺序进行编号。可以和 partition by 子句配合使用,也可以单独使用。
- frame 子句:当前分区的一个子集,用来定义子集的规则,通常用来作为滑动窗口使用。
窗口函数的作用

按照学号进行分组,对每组内的成绩进行排名



用到的脚本:
CREATE TABLE score (
-- 学号,假设长度固定,用 CHAR 类型,也可根据实际情况调整为 VARCHAR
student_id CHAR(4) NOT NULL,
-- 课程号,同样假设长度固定,用 CHAR 类型
course_id CHAR(4) NOT NULL,
-- 成绩,整数类型,存储分数
score INT,
PRIMARY KEY (student_id, course_id) -- 联合主键,保证学号和课程号组合唯一
);
INSERT INTO score (student_id, course_id, score)
VALUES
('0001', '0001', 80),
('0001', '0002', 90),
('0001', '0003', 99),
('0002', '0002', 60),
('0002', '0003', 80),
('0003', '0001', 80),
('0003', '0002', 80),
('0003', '0003', 80);
用到的脚本:
CREATE TABLE `employee` (
`empno` int NOT NULL,
`ename` varchar(50) DEFAULT NULL,
`job` varchar(50) DEFAULT NULL,
`hiredate` date DEFAULT NULL,
`sal` int DEFAULT NULL,
`dname` varchar(50) DEFAULT NULL,
PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7369, 'SMITH', 'CLERK', '1980-12-17', 800, 'ACCOUNTING');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7499, 'ALLEN', 'SALESMAN', '1981-02-20', 1600, 'SALES');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7521, 'WARD', 'SALESMAN', '1981-02-22', 1250, 'SALES');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7566, 'JONES', 'MANAGER', '1981-04-02', 2975, 'RESEARCH');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7654, 'MARTIN', 'SALESMAN', '1981-09-28', 1250, 'SALES');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7698, 'BLAKE', 'MANAGER', '1981-05-01', 2850, 'SALES');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7782, 'CLARK', 'MANAGER', '1981-06-09', 2450, 'ACCOUNTING');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7788, 'SCOTT', 'ANALYST', '1987-07-13', 3000, 'RESEARCH');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7839, 'KING', 'PRESIDENT', '1981-11-17', 5000, 'ACCOUNTING');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7844, 'TURNER', 'SALESMAN', '1981-09-08', 1500, 'SALES');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7876, 'ADAMS', 'CLERK', '1987-07-13', 1100, 'SALES');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7900, 'JAMES', 'CLERK', '1981-12-03', 950, 'SALES');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7902, 'FORD', 'ANALYST', '1981-12-03', 3000, 'RESEARCH');
INSERT INTO `test`.`employee` (`empno`, `ename`, `job`, `hiredate`, `sal`, `dname`) VALUES (7934, 'MILLER', 'CLERK', '1982-01-23', 1300, 'ACCOUNTING');
浙公网安备 33010602011771号