SQL查询多列唯一值方法:去除两列重复行获取不重复结果
需求背景
现有存在重复行的数据表,仅包含OS、Value两个字段,样例数据如下:
- OS列取值顺序:A、A、B、B
- 对应Value列取值顺序:5、10、5、10
需要实现两列同时去重的查询:最终结果集里OS值唯一、Value值也唯一,不要求两字段的固定匹配关系,期望输出为A对应5、B对应10。
SQL实现方案
核心逻辑是分别对去重后的OS、Value按相同排序规则生成连续序号,再通过序号关联配对,就能得到两列均无重复的结果集。
支持窗口函数的数据库版本(MySQL8.0+、PostgreSQL、SQL Server、Oracle等)
-- 替换语句中的'你的表名'为实际业务表名即可 WITH os_unique AS ( SELECT OS, ROW_NUMBER() OVER (ORDER BY OS) AS match_rn FROM 你的表名 GROUP BY OS ), value_unique AS ( SELECT Value, ROW_NUMBER() OVER (ORDER BY Value) AS match_rn FROM 你的表名 GROUP BY Value ) SELECT o.OS, v.Value FROM os_unique o INNER JOIN value_unique v ON o.match_rn = v.match_rn;
执行上述语句后会得到预期输出:
| OS | Value |
|---|---|
| A | 5 |
| B | 10 |
不支持窗口函数的旧版本数据库(如MySQL 5.x)
可以用用户变量模拟序号生成逻辑,代码如下:
-- 替换语句中的'你的表名'为实际业务表名即可 SELECT o.OS, v.Value FROM ( SELECT OS, @os_rn := @os_rn + 1 AS match_rn FROM (SELECT DISTINCT OS FROM 你的表名 ORDER BY OS) t_os, (SELECT @os_rn := 0) init_os ) o INNER JOIN ( SELECT Value, @val_rn := @val_rn + 1 AS match_rn FROM (SELECT DISTINCT Value FROM 你的表名 ORDER BY Value) t_val, (SELECT @val_rn := 0) init_val ) v ON o.match_rn = v.match_rn;
说明:如果需要调整OS和Value的配对规则,只需要修改两个CTE/子查询里
ORDER BY后的字段即可,只要两边排序规则一致,最终输出的两列就都不会出现重复值。
内容的提问来源于stack exchange,提问作者Renato Sandoval
相关产品推荐
相关产品推荐

