0
点赞
收藏
分享

微信扫一扫

MySQL8常见窗口函数:在一组相关行上进行复杂的计算,同时保留每一行的原始数据


MySQL 8.0 引入了窗口函数(Window Functions),这些函数允许你在一组相关行上进行复杂的计算,同时保留每一行的原始数据。窗口函数在数据分析和报表生成中非常有用。以下是一些常见的窗口函数及其使用示例。

1. ROW_NUMBER()

ROW_NUMBER() 函数为每个分区内的行分配一个唯一的序号。

示例

假设我们有一个 sales 表,记录了每个产品的每天销售额:

CREATE TABLE sales (
    id INT AUTO_INCREMENT PRIMARY KEY,
    product_name VARCHAR(50),
    sale_date DATE,
    quantity INT,
    price DECIMAL(10, 2)
);

INSERT INTO sales (product_name, sale_date, quantity, price) VALUES
('Product A', '2023-10-01', 2, 100.00),
('Product A', '2023-10-02', 3, 200.00),
('Product A', '2023-10-03', 1, 150.00),
('Product B', '2023-10-01', 1, 150.00),
('Product B', '2023-10-02', 2, 100.00),
('Product B', '2023-10-03', 3, 250.00);

计算每个产品每天的行号:

SELECT 
    product_name,
    sale_date,
    quantity,
    price,
    ROW_NUMBER() OVER (PARTITION BY product_name ORDER BY sale_date) AS row_num
FROM 
    sales
ORDER BY 
    product_name, 
    sale_date;

2. RANK()

RANK() 函数为每个分区内的行分配一个排名,如果有并列的行,排名会跳过相应的数字。

示例

计算每个产品每天的销售额排名:

SELECT 
    product_name,
    sale_date,
    quantity,
    price,
    RANK() OVER (PARTITION BY product_name ORDER BY price DESC) AS rank_num
FROM 
    sales
ORDER BY 
    product_name, 
    sale_date;

3. DENSE_RANK()

DENSE_RANK() 函数类似于 RANK(),但它不会跳过排名。

示例

计算每个产品每天的销售额密集排名:

SELECT 
    product_name,
    sale_date,
    quantity,
    price,
    DENSE_RANK() OVER (PARTITION BY product_name ORDER BY price DESC) AS dense_rank_num
FROM 
    sales
ORDER BY 
    product_name, 
    sale_date;

4. LEAD()LAG()

LEAD()LAG() 函数用于访问当前行之后或之前的行的数据。

示例

计算每个产品每天的前一日销售额:

SELECT 
    product_name,
    sale_date,
    quantity,
    price,
    LAG(price) OVER (PARTITION BY product_name ORDER BY sale_date) AS previous_day_price
FROM 
    sales
ORDER BY 
    product_name, 
    sale_date;

5. SUM()

SUM() 函数用于计算累计和。

示例

计算每个产品每天的累计销售额:

SELECT 
    product_name,
    sale_date,
    quantity,
    price,
    SUM(quantity * price) OVER (PARTITION BY product_name ORDER BY sale_date) AS cumulative_sales
FROM 
    sales
ORDER BY 
    product_name, 
    sale_date;

6. AVG()

AVG() 函数用于计算平均值。

示例

计算每个产品每天的滚动平均销售额:

SELECT 
    product_name,
    sale_date,
    quantity,
    price,
    AVG(quantity * price) OVER (PARTITION BY product_name ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS rolling_avg_sales
FROM 
    sales
ORDER BY 
    product_name, 
    sale_date;

7. MIN()MAX()

MIN()MAX() 函数用于计算最小值和最大值。

示例

计算每个产品每天的最大销售额:

SELECT 
    product_name,
    sale_date,
    quantity,
    price,
    MAX(price) OVER (PARTITION BY product_name ORDER BY sale_date) AS max_sales
FROM 
    sales
ORDER BY 
    product_name, 
    sale_date;

8. NTILE()

NTILE() 函数将分区内的行分成指定数量的桶。

示例

将每个产品的销售记录分成3个桶:

SELECT 
    product_name,
    sale_date,
    quantity,
    price,
    NTILE(3) OVER (PARTITION BY product_name ORDER BY sale_date) AS ntile_num
FROM 
    sales
ORDER BY 
    product_name, 
    sale_date;

总结

窗口函数在MySQL 8.0中提供了强大的数据分析能力。通过这些函数,你可以在一组相关行上进行复杂的计算,同时保留每一行的原始数据。


举报

相关推荐

0 条评论