适用场景
窗口函数适用场景: 对分组统计结果中的每一条记录进行计算的场景下, 使用窗口函数更好, 注意, 是每一条;因为MySQL的普通聚合函数的结果(如 group by)是每一组只有一条记录。
准备数据
创建表
create table app_product
(
id bigint auto_increment comment '主键'
primary key,
product_name varchar(100) null comment '产品名称',
product_type varchar(100) null comment '产品类型',
price int null comment '价格'
)
comment '产品表';
准备数据:
INSERT INTO app_product (id, product_name, product_type, price) VALUES (1, 'A1', 'A', 20);
INSERT INTO app_product (id, product_name, product_type, price) VALUES (2, 'A2', 'A', 40);
INSERT INTO app_product (id, product_name, product_type, price) VALUES (3, 'A3', 'A', 60);
INSERT INTO app_product (id, product_name, product_type, price) VALUES (4, 'B1', 'B', 10);
INSERT INTO app_product (id, product_name, product_type, price) VALUES (5, 'B2', 'B', 30);
INSERT INTO app_product (id, product_name, product_type, price) VALUES (6, 'B3', 'B', 50);
INSERT INTO app_product (id, product_name, product_type, price) VALUES (7, 'C1', 'C', 23);
INSERT INTO app_product (id, product_name, product_type, price) VALUES (8, 'C4', 'C', 57);
使用示例
使用别名
SELECT *,row_number() OVER w AS priceRank
FROM app_product
WINDOW w AS (PARTITION BY product_type ORDER BY price DESC);
序号函数
按照产品分类,按照价格排序。
row_number()
顺序展示编号
SELECT
*,
row_number() OVER (PARTITION BY product_type ORDER BY price DESC) AS priceRank
FROM
app_product;
获取每个分类的前3个价格高的产品
select * from (SELECT
*,
row_number() OVER (PARTITION BY product_type ORDER BY price DESC) AS priceRank
FROM
app_product) t where priceRank <=3;
rank()
,同等级同序号,序号不连续。
SELECT
*,
RANK() OVER (PARTITION BY product_type ORDER BY price DESC) AS priceRank
FROM
app_product;
dense_rank()
,同等级同序号,序号连续。
SELECT
*,
dense_rank() OVER (PARTITION BY product_type ORDER BY price DESC) AS priceRank
FROM
app_product;
分布函数
percent_rank()
,等级值百分比。(rank-1)/(rows-1)
SELECT *,
percent_rank() OVER (PARTITION BY product_type ORDER BY price DESC) AS priceRank
FROM app_product;
cume_dist()
,累积分布值。小于等于rank值的行数/总行数
SELECT *,
cume_dist() OVER (PARTITION BY product_type ORDER BY price DESC) AS priceRank
FROM app_product;
前后函数
LAG(expr, n)
- 返回当前行的前n行(本组内)的expr值
SELECT *,
lag(price,1) OVER (PARTITION BY product_type ORDER BY price DESC) AS pre_price
FROM app_product;
LEAD(expr, n)
返回当前行的后n行(本组)的expr值
SELECT *,
lead(price,1) OVER (PARTITION BY product_type ORDER BY price DESC) AS post_price
FROM app_product;
首位行数
first_value(expr)
获取分组内第一行数据 , last_value(expr)
获取分组内最后一行数据,nth_value(price,2)
获取分组内第n行的数据。
SELECT *,
first_value(price) OVER w first_price,last_value(price) OVER w last_price,nth_value(price,2) over w nTh_price
FROM app_product WINDOW w AS (PARTITION BY product_type ORDER BY price DESC);