第一篇笔记窗口函数(Window Function),记录我学习sql的命苦笔记

窗口函数(Window Function)是:在不减少数据行数的前提下,对数据进行排名/计算/统计。。。

区分与group by:

SELECT category, SUM(total_sales)

FROM sales

GROUP BY category;

如果caegory 1 里面有好几个单品,用group by 不会告诉你每个单品的total------sales是多少,它会把category 1里面的所有sales都加起来。

而窗口不合并行,只"算数"。原来几行 → 还是几行。每一行多了一个"计算结果"。适合:排名、占比、累计、对比

SELECT category, SUM(total_sales) AS cat_sales

FROM sales

GROUP BY category;

category cat_sales
C1 19
C2 36
C3 24

SELECT

product_id,

category,

total_sales,

SUM(total_sales) OVER (PARTITION BY category) AS cat_sales

FROM sales;

product_id category total_sales cat_sales
1 C1 12 19
2 C1 7 19
3 C2 14 36
4 C2 22 36
5 C3 24 24

窗口函数的标准结构:

函数名() OVER (

PARTITION BY 分组规则

ORDER BY 排序规则

)

函数名:你要"算什么"?

ROW_NUMBER():强制唯一名次(1,2,3...)

RANK():并列会跳号(1,2,2,4)

DENSE_RANK():并列不跳号(1,2,2,3)

PARTITION BY:在哪些"范围"里算:

PARTITION BY category (每个category单独算)

PARTITION BY ≠ GROUP BY,回到我前面说过的

用 GROUP BY 的典型问题

"每个类别的总销量是多少?"

"每个部门的人数是多少?"

"每个用户的平均评分是多少?"

特点:每组只要一行答案

用 PARTITION BY 的典型问题

"每个商品在类内的排名?"

"每一行占本组总量的比例?"

"每一行与本组平均值差多少?"

特点:答案必须仍然按行存在(因为你要给每个商品/订单一个排名或对比)

ORDER BY:决定计算顺序

ORDER BY total_sales DESC, product_id ASC (先按销量高的排前面,销量一样,用 product_id 打破平局)

注意:这是给窗口函数用的排序,和查询最后的 ORDER BY 是两回事

例题:牛客刷题SQL48 每个商品的销售总额