同一表Union与Join使用问题:如何避免ID引发的重复行
问题:为Union结果添加关联ID并避免重复行
表结构
现有表TableA结构如下:
id| origin1 | origin2 | col4 .... 1 | a | a | 434 2 | c | b | 439 3 | d | d | 8734
现有实现(获取唯一URL)
已通过UNION获取origin1与origin2的所有唯一值:
SELECT * FROM ( SELECT origin1 as url, 'home' as source FROM TableA UNION SELECT origin2 as url, 'home2' FROM TableA ) AS data
需求与问题
需要为每行添加原表ID以关联其他表,编写的语句如下:
select id_1 as id, url, col4,.... FROM ( SELECT origin1 as url, 'home' as source, id as id_1 FROM TableA UNION SELECT origin2 as url, 'home2', id FROM TableA ) AS data left join TableA on id_1 = TableA.id
期望结果:
id| url | col4 .... 1 | a | 434 2 | c | 439 2 | b | 439 3 | d | 8734
但实际执行后因ID和source字段的存在,导致大量重复行(比如ID=1的a会出现两次)。
解决方案
核心是先拆分origin1和origin2为独立行,再对同一原表ID下的重复URL去重,无需引入source字段(除非业务确实需要)。
简洁写法
直接在拆分时带上所需字段,再用DISTINCT去重:
SELECT DISTINCT id, url, col4 FROM ( -- 用UNION ALL拆分所有origin1和origin2的行,保留所有原始数据 SELECT id, origin1 AS url, col4 FROM TableA UNION ALL SELECT id, origin2 AS url, col4 FROM TableA ) AS data
解释
UNION ALL:仅拆分行,不自动去重,保留所有origin1和origin2的记录;DISTINCT:对id + url的组合去重,确保同一原表ID下相同URL只出现一次,避免重复行;- 无需额外
JOIN:拆分时直接携带col4等字段,减少关联操作。
如果业务需要保留source标识,但仍需避免重复URL,则可以调整为:
SELECT id, url, col4, MIN(source) AS source FROM ( SELECT id, origin1 AS url, col4, 'home' AS source FROM TableA UNION ALL SELECT id, origin2 AS url, col4, 'home2' AS source FROM TableA ) AS data GROUP BY id, url, col4
通过GROUP BY按id + url分组,选择任意一个source即可。
内容的提问来源于stack exchange,提问作者Daniel Illouz
相关产品推荐
相关产品推荐

