PostgreSQL:扁平化与数组的关系,每个数组条目发出一行

Cha*_*ffy 9 sql arrays postgresql lateral set-returning-functions

给定一个如此定义的表:

CREATE TABLE test_values(name TEXT, values INTEGER[]);
Run Code Online (Sandbox Code Playgroud)

......以及以下值:

| name  | values  |
+-------+---------+
| hello | {1,2,3} |
| world | {4,5,6} |
Run Code Online (Sandbox Code Playgroud)

我正在尝试查找将返回的查询:

| name  | value |
+-------+-------+
| hello | 1     |
| hello | 2     |
| hello | 3     |
| world | 4     |
| world | 5     |
| world | 6     |
Run Code Online (Sandbox Code Playgroud)

我已经回顾了有关访问数组的上游文档,并试图考虑使用unnest()函数的解决方案是什么样的,但是它已经空洞了.

即使在阵列被扩展且没有主键的情况下存在大量列的情况下,理想的解决方案也将易于使用.处理具有多个数组的案例并不重要.

Erw*_*ter 12

可以像Raphaël建议的那样将set-returns函数unnest()放入SELECT列表中.但是在Postgres 9.3或更高版本中使用联接代替.将set-returns函数放入列表而不是列表中是更清晰,更可取,符合标准的方法:LATERALFROMSELECT

SELECT name, value
FROM   tbl, unnest(values) value;  -- implicit CROSS JOIN LATERAL
Run Code Online (Sandbox Code Playgroud)

一个细微的区别:这会values从结果中删除带有空/ NULL 的,因为unnest()返回没有行,而在FROM列表中将其转换为NULL值并且仍然返回.100%等效查询是:

SELECT t.name, v.value
FROM   tbl t
LEFT   JOIN unnest(t.values) v(value) ON true;
Run Code Online (Sandbox Code Playgroud)


Rap*_*aus 6

好吧,您提供数据,文档,所以...让我们混合一下;)

select 
 name, 
 unnest(values) as value 
from test_values
Run Code Online (Sandbox Code Playgroud)

参见SqlFiddle