如何从PostgreSQL多列多行中提取唯一值?
问题描述
假设我们有一个PostgreSQL表,创建语句如下:
CREATE TABLE example ( value_1 VARCHAR(255), value_2 VARCHAR(255), value_3 VARCHAR(255), value_4 VARCHAR(255), value_5 VARCHAR(255) );
每行的各列值均不相同,且所有行包含同一组值,仅列顺序不同。插入数据语句如下:
INSERT INTO example VALUES ('a', 'b', 'c', 'd', 'e'), ('b', 'c', 'd', 'e', 'a'), ('c', 'd', 'e', 'a', 'b'), ('d', 'e', 'a', 'b', 'c'), ('e', 'a', 'b', 'c', 'd');
查询表数据结果如下:
# SELECT * FROM example; value_1 | value_2 | value_3 | value_4 | value_5 ---------+---------+---------+---------+--------- a | b | c | d | e b | c | d | e | a c | d | e | a | b d | e | a | b | c e | a | b | c | d (5 rows)
需求:从多列多行中筛选所有唯一值,得到仅包含'a'、'b'、'c'、'd'、'e'的单列结果,无需考虑每个值所在的列及最终结果的顺序。
解决方案
以下是几种在PostgreSQL中实现需求的方法:
方法1:UNION ALL + DISTINCT
通过UNION ALL将所有列的数据合并到一个临时结果集,再用DISTINCT去重,逻辑直观易懂:
SELECT DISTINCT val AS unique_value FROM ( SELECT value_1 AS val FROM example UNION ALL SELECT value_2 AS val FROM example UNION ALL SELECT value_3 AS val FROM example UNION ALL SELECT value_4 AS val FROM example UNION ALL SELECT value_5 AS val FROM example ) AS all_values;
方法2:ARRAY构造 + unnest函数
将每行的所有列打包成数组,再用unnest函数将数组展开为单行数据,最后去重,代码更简洁:
SELECT DISTINCT unnest(ARRAY[value_1, value_2, value_3, value_4, value_5]) AS unique_value FROM example;
方法3:LATERAL横向连接(PostgreSQL 9.3+)
利用LATERAL允许子查询引用外层表列的特性,将多列转换为行后去重,是PostgreSQL处理列转行的常用方式:
SELECT DISTINCT val AS unique_value FROM example, LATERAL (VALUES (value_1), (value_2), (value_3), (value_4), (value_5)) AS t(val);
内容的提问来源于stack exchange,提问作者adrenalin
相关产品推荐
相关产品推荐

