SQL如何按CODE分组过滤US_PRICE与NON_US_PRICE相等的行
按CODE过滤表A中US_PRICE与NON_US_PRICE相等行的实现方法
原SQL的问题
你之前写的语句有两处核心错误:
- 语法不符合规范:
OVER (PARTITION BY CODE)是窗口函数的配套子句,必须跟在SUM/COUNT/ROW_NUMBER这类窗口函数之后,不能直接接在US_PRICE != NON_US_PRICE这种普通比较表达式后面 - 逻辑存在疏漏:SQL采用三值逻辑判断,当比较的两边任意一边是
NULL时,!=比较返回的结果是UNKNOWN而非TRUE/FALSE,直接用普通不等号过滤会把你需要保留的NON_US_PRICE为NULL的行也排除掉
正确实现方案
从你给出的预期结果看,不需要使用窗口分区语法,核心逻辑是逐行判断当前记录的两个价格是否完全相等,相等则移除,不相等(包含其中一个价格为NULL的场景)则保留。不同数据库的NULL安全比较写法略有区别:
全数据库兼容的标准SQL写法
SELECT * FROM A WHERE -- 两价格都非空时,判断值不相等 (US_PRICE IS NOT NULL AND NON_US_PRICE IS NOT NULL AND US_PRICE <> NON_US_PRICE) -- 保留仅一个价格为NULL的行 OR (US_PRICE IS NULL AND NON_US_PRICE IS NOT NULL) OR (US_PRICE IS NOT NULL AND NON_US_PRICE IS NULL);
各数据库简化写法
- MySQL:可以用自带的NULL安全相等运算符
<=>取反,写法更简洁
SELECT * FROM A WHERE NOT US_PRICE <=> NON_US_PRICE;
- PostgreSQL、Oracle:支持
IS DISTINCT FROMNULL安全比较语法
SELECT * FROM A WHERE US_PRICE IS DISTINCT FROM NON_US_PRICE;
- SQL Server:无专用NULL安全比较符,直接使用上述通用标准写法即可
结果校验
基于你提供的样例数据运行上述语句:
- CODE=5109:仅1条记录,两价格均为10,相等,被过滤
- CODE=0206:共3条记录,其中1条两价格均为11,相等被过滤;剩余2条价格分别为15/14、41/70,值不相等,保留
- CODE=T100:共2条记录,其中1条两价格均为38,相等被过滤;剩余1条NON_US_PRICE为NULL,属于不相等场景,保留
最终返回3条记录,和预期结果完全一致。
内容的提问来源于stack exchange,提问作者user18466310
相关产品推荐
相关产品推荐

