SQL GROUP BY合并多行:多列地区数据去重方案求助
解决多列地区数据的去重合并问题
嘿,这个需求其实很典型——就是要把分散在多列里的同类型数据收拢成一列,再提取唯一值对吧?我给你两个实用的方案,兼容性和简洁性都兼顾到了:
通用方案(适用于所有关系型数据库)
最稳妥的方法是用 UNION ALL 把三个地区列的数据先“堆叠”成单列表格,再通过 DISTINCT 去重,同时过滤掉空值:
SELECT DISTINCT region FROM ( -- 把三个列分别转成单独的行 SELECT region1 AS region FROM games UNION ALL SELECT region2 AS region FROM games UNION ALL SELECT region3 AS region FROM games ) AS all_regions -- 过滤掉空值和空白字符串,避免无效行 WHERE region IS NOT NULL AND region != '';
逻辑解释:
- 内层子查询通过三次
SELECT+UNION ALL,把region1、region2、region3的所有数据合并到一个名为region的列里; - 外层用
DISTINCT确保每个地区只出现一次; WHERE子句剔除那些空的或者空白的地区值,避免结果里出现无效的空行。
用你提供的示例数据测试的话,子查询会输出:us、fr、de、fr、uk、ru,经过DISTINCT去重后,正好得到你想要的唯一地区列表。
简洁方案(适用于支持高级函数的数据库)
如果你的数据库是PostgreSQL、MySQL 8.0+、SQL Server这类支持数组/JSON函数的,可以用更紧凑的写法:
PostgreSQL 版本
SELECT DISTINCT unnest(ARRAY[region1, region2, region3]) AS region FROM games WHERE unnest(ARRAY[region1, region2, region3]) IS NOT NULL AND unnest(ARRAY[region1, region2, region3]) != '';
这里用ARRAY[]把三个列打包成数组,再用unnest()把数组展开成单行数据,最后DISTINCT去重。
MySQL 版本
SELECT DISTINCT j.region FROM games, JSON_TABLE( -- 把三个列拼接成JSON数组格式 CONCAT('["', REPLACE(CONCAT(region1, ',', region2, ',', region3), ',', '","'), '"]'), '$[*]' COLUMNS (region VARCHAR(255) PATH '$') ) j WHERE j.region IS NOT NULL AND j.region != '';
通过CONCAT把三个列拼接成JSON字符串,再用JSON_TABLE把JSON数组转换成行数据,最后去重。
这两种简洁写法的效果和通用方案完全一致,只是代码更短,不过兼容性不如UNION ALL方案好,根据你的数据库类型选择就行。
内容的提问来源于stack exchange,提问作者Armin Hierstetter
相关产品推荐
相关产品推荐

