如何在SQL窗口函数中添加过滤条件统计指定时间范围非零金额计数
问题解答
能否直接在窗口函数后加where amt<>0实现需求?
不能,原因如下:
- SQL执行顺序中,
WHERE子句优先级高于窗口函数,全局加WHERE amt<>0会先过滤掉所有Amt为0的原始行,导致最终结果丢失你需要保留的Amt=0的记录,不符合预期输出要求。 - 窗口函数语法本身不支持直接在函数后追加
WHERE条件做行级过滤。
能否为窗口函数添加amt<>0的过滤条件实现按条件计数?
可以,有两种实现方式:
1. 通用兼容写法(支持所有支持窗口函数的数据库)
利用COUNT统计时自动忽略NULL值的特性,通过CASE条件表达式实现过滤:
-- 过去一周非零Amt出现次数 COUNT(CASE WHEN Amt <> 0 THEN 1 END) OVER ( PARTITION BY AccNo ORDER BY Date RANGE BETWEEN 7 PRECEDING AND 1 PRECEDING ) AS no_of_times_non_0_past_week, -- 过去一月非零Amt出现次数 COUNT(CASE WHEN Amt <> 0 THEN 1 END) OVER ( PARTITION BY AccNo ORDER BY Date RANGE BETWEEN 30 PRECEDING AND 1 PRECEDING ) AS no_of_times_non_0_past_month
注:示例中窗口范围设置为
1 PRECEDING是为了匹配你给出的预期结果(统计区间不包含当前行本身),如果需要包含当前行可以改回CURRENT ROW;另外需要先将Date字段转换为日期类型,避免字符串排序导致窗口范围计算错误。
2. 精简写法(仅PostgreSQL等支持FILTER子句的数据库可用)
如果你的数据库支持FILTER子句,可以用更直观的写法:
COUNT(Amt) FILTER (WHERE Amt <> 0) OVER ( PARTITION BY AccNo ORDER BY Date RANGE BETWEEN 7 PRECEDING AND 1 PRECEDING ) AS no_of_times_non_0_past_week
内容的提问来源于stack exchange,提问作者Another Day Another Data
相关产品推荐
相关产品推荐

