如何在SQL中实现多行多列不重复值的分组拼接?
实现多行多列邮箱拼接去重的SQL方案
没问题,我来帮你搞定这个SQL需求!你要的是把同一VAT下分散在多行、两列里的邮箱收集起来,去重后合并成一个逗号分隔的字符串对吧?核心思路是先把多列转成多行,再过滤空值、去重,最后分组拼接。下面针对不同主流数据库给你具体代码:
MySQL 实现
SELECT VAT, GROUP_CONCAT(DISTINCT email SEPARATOR ', ') AS Emails FROM ( -- 将两列邮箱拆分为独立行 SELECT VAT, Email1 AS email FROM your_table WHERE Email1 != '-' UNION ALL SELECT VAT, Email2 AS email FROM your_table WHERE Email2 != '-' ) AS temp WHERE email != '-' -- 确保过滤掉所有空值标识 GROUP BY VAT;
这里先用UNION ALL把Email1和Email2两列的内容转换成多行记录,同时过滤掉值为'-'的空项;外层通过GROUP_CONCAT配合DISTINCT实现去重后的字符串拼接,最后按VAT分组得到结果。
PostgreSQL 实现
SELECT VAT, STRING_AGG(DISTINCT email, ', ') AS Emails FROM ( SELECT VAT, Email1 AS email FROM your_table WHERE Email1 <> '-' UNION ALL SELECT VAT, Email2 AS email FROM your_table WHERE Email2 <> '-' ) AS temp WHERE email <> '-' GROUP BY VAT;
PostgreSQL用STRING_AGG函数来完成字符串拼接,逻辑和MySQL完全一致,只是不等于符号习惯用<>(当然MySQL也支持这个写法)。
SQL Server 2017及以上版本实现
SELECT VAT, STRING_AGG(DISTINCT email, ', ') WITHIN GROUP (ORDER BY email) AS Emails FROM ( SELECT VAT, Email1 AS email FROM your_table WHERE Email1 <> '-' UNION ALL SELECT VAT, Email2 AS email FROM your_table WHERE Email2 <> '-' ) AS temp WHERE email <> '-' GROUP BY VAT;
SQL Server 2017开始支持STRING_AGG函数,这里还额外加了WITHIN GROUP (ORDER BY email)来让拼接后的邮箱按字母顺序排列,如果你不需要排序可以去掉这部分。
补充说明
如果你的数据中空值不是用'-'表示,而是标准的NULL,只需要把WHERE条件改成WHERE email IS NOT NULL即可适配。
内容的提问来源于stack exchange,提问作者Martina
相关产品推荐
相关产品推荐

