我正在使用 Trino/Presto 并尝试取消嵌套数组列,该列可能包含具有空或空数组的行,这会导致此类行丢失:
with table1(id, arr) as (
values (1, array[1,2,3]),
(2, array[]),
(3, array[42]),
(4, null)
)
select id, a
from table1
cross join unnest(arr) as t(a);
并输出:
id | a
----+----
1 | 1
1 | 2
1 | 3
3 | 42
如您所见,id 2 和 4 丢失了。是否可以重写查询以便它们出现?
UNNEST
空值或空数组会生成空表。如果要保留该连接左侧的所有行,则需要使用 LEFT JOIN
而不是 CROSS JOIN
,因为后者在一侧为空时不会生成任何行。将联接操作视为左侧每一行与通过对该行中给定列的值调用 UNNEST 函数生成的表之间的联接。
WITH table1(id, arr) AS (
VALUES (1, array[1,2,3]),
(2, array[]),
(3, array[42]),
(4, null)
)
SELECT id, a
FROM table1
LEFT JOIN UNNEST(arr) AS t(a) ON true;
输出:
id | a
----+------
1 | 1
1 | 2
1 | 3
2 | NULL
3 | 42
4 | NULL
(6 rows)
unnest
允许指定多个要取消嵌套的数组,当它们具有不同的基数时,“缺失”值将用 null
填充,因此您可以使用它来解决问题(请注意 unnest
的简洁语法允许跳过cross join
):
-- query
select id, a
from table1,
unnest(arr, array[1]) as t(a, ignored);
或使用左连接:
-- query
select id, a
from table1
left join unnest(arr) as t(a) on true;