当Distinct无效时,如何在SQL查询中去除重复值?
嘿,我来帮你搞定这个SQL去重的问题!首先得说,你之前用UNIQUE没成功大概率是用错地方了——这个关键字一般是用来给表加唯一约束的,不是在查询里去重用的,查询去重得用DISTINCT才行。下面分两种情况给你解决方案,包括你要的“不限制列顺序”的场景:
1. 普通重复行(列顺序和值都完全一样)的去重
如果你的重复行是完全一模一样的(列的顺序和对应的值都没差),直接在查询里加DISTINCT就搞定了,这是最常用的方式:
-- 主查询直接去重,替换成你的列和条件 SELECT DISTINCT col1, col2, col3 FROM your_table WHERE ...;
要是你需要在子查询里先去重,同样用DISTINCT代替UNIQUE:
SELECT * FROM ( SELECT DISTINCT col1, col2 FROM your_table ) AS subquery;
2. 不限制列顺序的去重(列值换顺序也算重复)
如果你的需求是:哪怕两行的列值只是顺序换了(比如一行是(1,2),另一行是(2,1)),也得当成重复去掉,那得先把每行的列值排好序,再基于排序后的值去重。
两列的简单情况:用LEAST和GREATEST
只有两列的话,用LEAST(取最小值)和GREATEST(取最大值)把列值按固定顺序排列,再用DISTINCT去重:
SELECT DISTINCT LEAST(col_a, col_b) AS sorted_col1, GREATEST(col_a, col_b) AS sorted_col2 FROM your_query_result;
多列的通用情况:生成有序标识
要是有3列及以上,就把每行的列值排序后生成一个有序的数组或者字符串,再用这个标识来去重:
PostgreSQL示例:
用数组来存排序后的列值,然后用DISTINCT ON取每组唯一行:
WITH sorted_rows AS ( SELECT *, -- 把当前行的所有列值收集起来排序,生成有序数组 (SELECT ARRAY_AGG(val ORDER BY val) FROM (VALUES (col1), (col2), (col3)) AS vals(val)) AS sorted_vals FROM your_query_result ) SELECT DISTINCT ON (sorted_vals) col1, col2, col3 FROM sorted_rows;
MySQL示例:
把排序后的列值拼接成字符串,再分组取唯一行:
SELECT t.col1, t.col2, t.col3 FROM ( SELECT *, -- 把当前行的列值排序后拼接成字符串当唯一标识 (SELECT GROUP_CONCAT(val ORDER BY val SEPARATOR ',') FROM (SELECT col1 AS val UNION ALL SELECT col2 UNION ALL SELECT col3) AS vals) AS sorted_str FROM your_query_result ) t GROUP BY sorted_str;
最后再提醒下:UNIQUE是用来给表定义唯一约束的(比如确保某列不会有重复值),不是查询去重的关键字,以后去重记得用DISTINCT哦!
内容的提问来源于stack exchange,提问作者Vince
相关产品推荐
相关产品推荐

