PostgreSQL:筛选C列含X/Y不同时存在且B列无重复的行
PostgreSQL 筛选符合特定条件的行
需求
筛选满足以下条件的行:
- C列的值为
X或Y - 最终结果中,同一
B列值对应的行不能同时包含X和Y - 最终结果里
B列无重复值
数据示例
A | B | C | ---------------------------------------- 1 | John | X | ---------------------------------------- 2 | John | Y | ---------------------------------------- 3 | Sam | X | ---------------------------------------- 4 | May | Y |
预期结果
A | B | C | ---------------------------------------- 1 | John | X | ---------------------------------------- 3 | Sam | X | ---------------------------------------- 4 | May | Y |
解决方案
方法1:使用PostgreSQL特有的DISTINCT ON(推荐)
这种写法简洁高效,完美适配“按分组取唯一行”的场景:
SELECT DISTINCT ON (B) A, B, C FROM your_table WHERE C IN ('X', 'Y') -- 排序规则:先按B分组,同时有X/Y的B优先保留X的行,再按A列保证结果稳定 ORDER BY B, CASE WHEN C = 'X' THEN 0 ELSE 1 END, A;
方法2:窗口函数实现(通用SQL语法)
如果需要兼容其他数据库,或者需要更灵活的逻辑控制,可采用窗口函数写法:
WITH ranked_rows AS ( SELECT A, B, C, ROW_NUMBER() OVER ( PARTITION BY B ORDER BY CASE WHEN C = 'X' THEN 0 ELSE 1 END, A ) AS rn FROM your_table WHERE C IN ('X', 'Y') ) SELECT A, B, C FROM ranked_rows WHERE rn = 1 ORDER BY A;
逻辑说明
- 两种方法都先通过
WHERE C IN ('X', 'Y')筛选出C列符合要求的行 - 对于同一
B下同时存在X和Y的情况(比如John的行),通过排序规则优先保留X的行;若需要优先保留Y,只需调整CASE语句的顺序即可 - 最终确保每个
B值在结果中只出现一次,完全满足需求
内容的提问来源于stack exchange,提问作者inquisitive
相关产品推荐
相关产品推荐

