展平与数组的关系以针对每个数组条目发出一行
Flattening a relation with an array to emit one row per array entry
给定一个 table 定义如下:
CREATE TABLE test_values(name TEXT, values INTEGER[]);
...以及以下值:
| name | values |
+-------+---------+
| hello | {1,2,3} |
| world | {4,5,6} |
我正在尝试查找将 return:
| name | value |
+-------+-------+
| hello | 1 |
| hello | 2 |
| hello | 3 |
| world | 4 |
| world | 5 |
| world | 6 |
我看过 the upstream documentation on accessing arrays, and tried to think about what a solution using the unnest()
function 看起来像,但一直空着。
理想的解决方案即使在除了要扩展的数组之外还有大量列且没有主键的情况下也易于使用。处理多个数组的情况并不重要。
好吧,你给了数据,文档,所以......让我们混合它;)
select
name,
unnest(values) as value
from test_values
我们可以把set-returning函数放上去unnest()
into the SELECT
list 。这用于在 Postgres 10 之前展示极端案例问题。请参阅:
从 Postgres 9.3 开始,我们也可以为此使用 LATERAL
连接。这是将返回集合的函数放入 FROM
列表而不是 SELECT
列表的更简洁、符合标准的方法:
SELECT name, value
FROM tbl, unnest(values) value; -- implicit CROSS JOIN LATERAL
一个细微的差别:由于 unnest()
returns 没有行 ,这会从结果中删除带有空/NULL values
的行,而same 在 FROM
列表中被转换为 NULL 值并返回。 100% 等效查询是:
SELECT t.name, v.value
FROM tbl t
LEFT JOIN unnest(t.values) v(value) ON true;
参见:
给定一个 table 定义如下:
CREATE TABLE test_values(name TEXT, values INTEGER[]);
...以及以下值:
| name | values |
+-------+---------+
| hello | {1,2,3} |
| world | {4,5,6} |
我正在尝试查找将 return:
| name | value |
+-------+-------+
| hello | 1 |
| hello | 2 |
| hello | 3 |
| world | 4 |
| world | 5 |
| world | 6 |
我看过 the upstream documentation on accessing arrays, and tried to think about what a solution using the unnest()
function 看起来像,但一直空着。
理想的解决方案即使在除了要扩展的数组之外还有大量列且没有主键的情况下也易于使用。处理多个数组的情况并不重要。
好吧,你给了数据,文档,所以......让我们混合它;)
select
name,
unnest(values) as value
from test_values
我们可以把set-returning函数放上去unnest()
into the SELECT
list
从 Postgres 9.3 开始,我们也可以为此使用 LATERAL
连接。这是将返回集合的函数放入 FROM
列表而不是 SELECT
列表的更简洁、符合标准的方法:
SELECT name, value
FROM tbl, unnest(values) value; -- implicit CROSS JOIN LATERAL
一个细微的差别:由于 unnest()
returns 没有行 ,这会从结果中删除带有空/NULL values
的行,而same 在 FROM
列表中被转换为 NULL 值并返回。 100% 等效查询是:
SELECT t.name, v.value
FROM tbl t
LEFT JOIN unnest(t.values) v(value) ON true;
参见: