如何编写多条件SQL查询:筛选月度非SALE ID=1的CHARGE总和为0的ORG
问题描述
原始数据表
| ORG(机构) | SALE ID(销售ID) | CHARGE(费用) | MONTH(月份) |
|---|---|---|---|
| AA | 1 | 20 | NOV |
| AA | 2 | 30 | DEC |
| BB | 1 | 20 | DEC |
| BB | 2 | 00 | DEC |
| BB | 3 | 00 | DEC |
| BB | 1 | 20 | NOV |
| BB | 2 | 00 | NOV |
| CC | 3 | 00 | DEC |
查询需求
找出每个月份下,所有销售ID不等于1的费用字段总和为0的机构记录,预期结果如下:
| ORG(机构) | MONTH(月份) |
|---|---|
| BB | NOV |
| BB | DEC |
| CC | DEC |
尝试的SQL(未得到正确结果)
SELECT "MONTH", "ORG" FROM (SELECT DISTINCT "MONTH" , "CHARGE", "SALE_ID" ,"ORG" CASE WHEN "SALE_ID" != 1 AND "SALE_ID" IS NOT NULL AND SUM("CHARGE") OVER(PARTITION BY "ORG", "MONTH" )=0 THEN "ORG" END FROM "TABLE" WHERE "MONTH" >= '01-JAN-2023' ) GROUP BY "MONTH", "ORG"
问题分析与正确SQL
你的尝试存在几个核心问题:
- 误用
DISTINCT,会破坏原始数据的聚合逻辑,完全没必要添加 - 窗口函数计算的是该机构当月全部记录的费用总和,没有过滤
SALE_ID = 1的记录,不符合需求 - 子查询存在语法错误:
CASE语句前缺少逗号,且子查询未指定别名 - 外层
GROUP BY逻辑混乱,没有明确的筛选条件
正确的思路是:按机构和月份分组,仅统计SALE_ID != 1的费用总和,再筛选总和为0的分组。
正确SQL语句
SELECT "ORG", "MONTH" FROM "TABLE" WHERE "MONTH" >= '01-JAN-2023' GROUP BY "ORG", "MONTH" HAVING SUM(CASE WHEN "SALE_ID" != 1 THEN "CHARGE" ELSE 0 END) = 0;
逻辑说明
CASE WHEN "SALE_ID" != 1 THEN "CHARGE" ELSE 0 END:仅纳入销售ID不等于1的费用,其余情况按0计算,避免干扰总和SUM(...):对每个机构-月份组,计算上述筛选后的费用总和HAVING SUM(...) = 0:直接筛选出总和为0的分组,即为符合需求的记录
内容的提问来源于stack exchange,提问作者Avangard
相关产品推荐
相关产品推荐

