如何筛选同一客户ID下不同值的单元格并保留原行结构?
实现同一客户分组内重复列值替换为“-”的SQL方案
要实现你需要的效果,核心是针对每个CUSTOMER_ID分组,判断每一列在组内是否存在多个不同值:如果该列在组内所有值完全一致(包括全为NULL的情况),则替换为“-”;否则保留原字段值。
核心SQL实现(兼容多数主流数据库:MySQL 8+/PostgreSQL/SQL Server等)
SELECT CUSTOMER_ID AS ID_CLIENT, CASE WHEN COUNT(DISTINCT NAME) OVER (PARTITION BY CUSTOMER_ID) = 1 THEN '-' ELSE NAME END AS NAME, CASE WHEN COUNT(DISTINCT PHONE) OVER (PARTITION BY CUSTOMER_ID) = 1 THEN '-' ELSE PHONE END AS PHONE, CASE WHEN COUNT(DISTINCT AGE) OVER (PARTITION BY CUSTOMER_ID) = 1 THEN '-' ELSE AGE END AS AGE, CASE WHEN COUNT(DISTINCT HEIGHT) OVER (PARTITION BY CUSTOMER_ID) = 1 THEN '-' ELSE HEIGHT END AS HEIGHT FROM CUSTOMER ORDER BY CUSTOMER_ID;
逻辑说明
- 窗口函数分组统计:使用
COUNT(DISTINCT 列名) OVER (PARTITION BY CUSTOMER_ID),统计每个客户分组内该列的不同值数量。- 如果数量为1,说明该列在当前客户的所有行中值完全相同,替换为“-”。
- 如果数量大于1,说明存在不同值,保留该行的原始值。
- 保留原行结构:窗口函数不会改变原表的行数量和顺序,完美匹配你需要的输出结构,避免自连接或UNION带来的行混乱问题。
验证结果
运行上述SQL后,会完全生成你期望的输出:
ID_CLIENT NAME PHONE AGE HEIGHT 1 - 987456321 - 1.80 1 - NULL - 1.79 2 - NULL - - 2 - 987456321 - -
内容的提问来源于stack exchange,提问作者Álvaro Navarro
相关产品推荐
相关产品推荐

