1. 选表
- FROM
2. 联表
- JOIN ON
3. 原始行过滤
- WHERE
4. 分组
- GROUP BY
5. 组级过滤
- HAVING
6. 投影及分析计算
- SELECT
- DISTINCT
- OVER
- PARTITION BY
- ORDER BY
- ROWS/RANGE/GROUPS BETWEEN AND
7. 排序与结果裁剪
- ORDER BY
- LIMIT
- OFFSET
窗口帧(Window Frame)关键字
txt复制代码
ROWS | RANGE | GROUPS
BETWEEN <frame_start> AND <frame_end>
样例
sql复制代码
DROP TABLE IF EXISTS student;
CREATE TABLE student (
sid INT PRIMARY KEY, -- 学号
name VARCHAR(50), -- 学生姓名
class_id INT, -- 班级编号
score INT -- 分数
);
INSERT INTO student (sid, name, class_id, score) VALUES
-- A班
(1, 'Alice', 101, 85),
(2, 'Bob', 101, 90),
(3, 'Charlie', 101, 78),
(4, 'David', 101, 90),
-- B班
(5, 'Eve', 102, 88),
(6, 'Frank', 102, 76),
(7, 'Grace', 102, 95),
(8, 'Heidi', 102, 84),
-- C班
(9, 'Ivan', 103, 70),
(10, 'Judy', 103, 82),
(11, 'Mallory', 103, 78),
(12, 'Niaj', 103, 85),
-- D班
(13, 'Olivia', 104, 91),
(14, 'Peggy', 104, 87),
(15, 'Sybil', 104, 79),
(16, 'Trent', 104, 93);
SELECT
sid,
class_id,
score,
AVG(score) OVER (PARTITION BY class_id) AS avg_score, -- 班级平均分
MAX(score) OVER (PARTITION BY class_id) AS max_score, -- 班级最高分
MIN(score) OVER (PARTITION BY class_id) AS min_score -- 班级最低分
FROM
student;
SELECT
sid,
class_id,
score,
RANK() OVER (PARTITION BY class_id ORDER BY score DESC) AS rank_in_class, -- 排名(有并列,有空缺)
DENSE_RANK() OVER (PARTITION BY class_id ORDER BY score DESC) AS DENSE_RANK, -- 排名(有并列,无空缺)
ROW_NUMBER() OVER (PARTITION BY class_id ORDER BY score DESC) AS row_num -- 排名 (无并列,无空缺)
FROM
student;
SELECT
sid,
class_id,
score,
SUM(score) OVER (PARTITION BY class_id ORDER BY score ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_score
FROM
student;
SELECT
sid,
score,
class_id,
SUM(score) OVER (PARTITION BY class_id ORDER BY score RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_sum
FROM
student;
SELECT
sid,
score,
class_id,
SUM(score) OVER (PARTITION BY class_id ORDER BY score GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_sum
FROM
student;
SELECT
sid,
class_id,
score,
LAG(score) OVER (PARTITION BY class_id ORDER BY score) AS prev_score, -- 上一行分数
LEAD(score) OVER (PARTITION BY class_id ORDER BY score) AS next_score -- 下一行分数
FROM
student;
SELECT
sid,
class_id,
score,
AVG(score) OVER (PARTITION BY class_id) AS avg_score,
RANK() OVER (PARTITION BY class_id ORDER BY score DESC) AS rank_in_class,
CASE
WHEN score > AVG(score) OVER (PARTITION BY class_id) THEN
'above_avg'
ELSE
'below_avg'
END AS performance
FROM
student;