我经常使用这样的构造:
SELECT *
FROM
my_table,
my_srf(my_column)
例如这里:
CREATE TABLE my_table (
my_col text[]
);
INSERT INTO my_table VALUES
('{a,b}'),
('{c,d,e}');
SELECT
*
FROM
my_table,
unnest(my_col);
结果如预期:
my_col unnest
{a,b} a
{a,b} b
{c,d,e} c
{c,d,e} d
{c,d,e} e
现在我稍微考虑了这个结构并感到困惑。逗号符号是 as 的快捷方式CROSS JOIN
。事实上,这也有效:
SELECT
*
FROM
my_table
CROSS JOIN
unnest(my_col)
但是因为这是一个交叉连接,所以这个结果对我来说看起来更合乎逻辑:
my_col unnest
{a,b} a
{a,b} b
{a,b} c
{a,b} d
{a,b} e
{c,d,e} a
{c,d,e} b
{c,d,e} c
{c,d,e} d
{c,d,e} e
交叉连接将一个部分的所有记录与另一部分的所有记录连接起来。
尽管我如上所述使用此 SRF 连接,但我现在不再确定它为什么会详细工作。所以,我认为到目前为止我显然不了解 SRF 的完整功能。
因为文档让我不太清楚,所以我想请你解释一下这种行为。
您缺少的部分是,这不是常规的交叉连接,而是“横向”交叉连接。
所以完整的等价物是:
如果连接是针对一个集合返回函数完成的,那么关键字 LATERAL 是隐式假设的,这就是为什么
cross join unnest(my_col)
甚至也可以from my_table, unnest(my_col)
工作。将
LATERAL
更改交叉连接,使其从my_table
该(一)行中获取一行并与从集合返回函数返回的所有行进行交叉连接。然后它对下一行做同样的事情,依此类推。因此它会在包含数组的行
{a,b}
与其所有元素之间生成交叉连接。{c,d,e}
然后与包含数组及其所有元素的行进行另一个交叉连接。手册是这样解释的: