COUNT() OVER()总结

COUNT() OVER() 是 Impala 中非常重要的窗口函数用法,它与普通的聚合函数 COUNT() 有本质区别。

核心概念

COUNT() OVER() 不是在查询结果上做整体聚合,而是为每一行计算一个计数值,同时保留所有原始行的详细信息。

基本语法

COUNT(*) OVER (
    [PARTITION BY column1, column2...]
    [ORDER BY column3, ...]
    [window_frame_clause]
)

主要用法和示例

假设我们有 sales 表:

sale_idproductcategorysale_dateamount
1iPhonePhone2024-01-011000
2GalaxyPhone2024-01-02900
3iPadTablet2024-01-03800
4MacBookLaptop2024-01-042000
5PixelPhone2024-01-05700

1. 简单的 COUNT() OVER() - 计算总行数

SELECT 
    sale_id,
    product,
    amount,
    COUNT(*) OVER() as total_count
FROM sales;

结果:

sale_idproductamounttotal_count
1iPhone10005
2Galaxy9005
3iPad8005
4MacBook20005
5Pixel7005

说明: 每行都显示总行数 5,但保留了所有原始数据。

2. 使用 PARTITION BY - 按分组计数

SELECT 
    sale_id,
    product,
    category,
    amount,
    COUNT(*) OVER(PARTITION BY category) as category_count
FROM sales;

结果:

sale_idproductcategoryamountcategory_count
4MacBookLaptop20001
1iPhonePhone10003
2GalaxyPhone9003
5PixelPhone7003
3iPadTablet8001

说明: 在每个 category 分组内分别计数,Phone 类别有3条记录,Laptop 和 Tablet 各有1条。

3. 使用 ORDER BY - 累计计数

SELECT 
    sale_id,
    product,
    sale_date,
    amount,
    COUNT(*) OVER(ORDER BY sale_date) as running_count
FROM sales;

结果:

sale_idproductsale_dateamountrunning_count
1iPhone2024-01-0110001
2Galaxy2024-01-029002
3iPad2024-01-038003
4MacBook2024-01-0420004
5Pixel2024-01-057005

说明: 按日期排序后,每行显示到当前行为止的累计行数。

4. 结合 PARTITION BYORDER BY - 分组内累计

SELECT 
    sale_id,
    product,
    category,
    sale_date,
    amount,
    COUNT(*) OVER(
        PARTITION BY category 
        ORDER BY sale_date
    ) as running_count_in_category
FROM sales;

结果:

sale_idproductcategorysale_dateamountrunning_count_in_category
4MacBookLaptop2024-01-0420001
1iPhonePhone2024-01-0110001
2GalaxyPhone2024-01-029002
5PixelPhone2024-01-057003
3iPadTablet2024-01-038001

说明: 在每个 category 分组内,按日期顺序进行累计计数。


实际应用场景

场景1:计算占比

SELECT 
    product,
    amount,
    COUNT(*) OVER() as total_orders,
    ROUND(amount * 100.0 / SUM(amount) OVER(), 2) as amount_percent
FROM sales;

场景2:识别重复数据

SELECT *
FROM (
    SELECT 
        *,
        COUNT(*) OVER(PARTITION BY product, category) as duplicate_count
    FROM sales
) t
WHERE duplicate_count > 1;

场景3:分析数据密度

SELECT 
    sale_date,
    amount,
    COUNT(*) OVER(ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) as last_3_days_count
FROM sales;

与普通 COUNT() 的关键区别

特性普通 COUNT()COUNT() OVER()
返回结果单行聚合结果为每行返回一个计数值
数据保留丢失原始行细节保留所有原始列数据
使用场景整体统计行级分析、排名、占比计算
分组方式GROUP BYPARTITION BY

总结

COUNT() OVER() 的强大之处在于:

  1. 保留明细:不像 GROUP BY 那样折叠数据
  2. 灵活分组:通过 PARTITION BY 实现多维度分析
  3. 支持排序:通过 ORDER BY 实现累计计算
  4. 窗口控制:可以定义更复杂的计算范围(如最近N行)

这使得它成为数据分析、报表制作和复杂业务逻辑实现的利器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值