jpe*_*lli 5 sql postgresql cross-join set-returning-functions
我试图通过两个set-returns函数得到一个"交叉连接",但在某些情况下我没有得到"交叉连接",请参阅示例
行为1:当设置的长度相同时,它会逐个匹配每个集合中的项目
postgres=# SELECT generate_series(1,3), generate_series(5,7) order by 1,2; generate_series | generate_series -----------------+----------------- 1 | 5 2 | 6 3 | 7 (3 rows)
行为2:当设置的长度不同时,它会"交叉连接"这些集合
postgres=# SELECT generate_series(1,2), generate_series(5,7) order by 1,2; generate_series | generate_series -----------------+----------------- 1 | 5 1 | 6 1 | 7 2 | 5 2 | 6 2 | 7 (6 rows)
我想我在这里不了解一些事情,有人可以解释一下这种行为吗?
编辑:另一个例子,比以前更奇怪
postgres=# SELECT generate_series(1,2) x, generate_series(1,4) y order by x,y; x | y ---+--- 1 | 1 1 | 3 2 | 2 2 | 4 (4 rows)
(注意:我会接受回答标题问题并附有文档链接的答案.)
Erw*_*ter 10
为较小的集添加空值.演示generate_series()
:
SELECT generate_series( 1, 2) AS row2
, generate_series(11, 13) AS row3
, generate_series(21, 24) AS row4;
Run Code Online (Sandbox Code Playgroud)
row2 | row3 | row4 -----+------+----- 1 | 11 | 21 2 | 12 | 22 null | 13 | 23 null | null | 24
dbfiddle 在这里
如果查询的选择列表中有多个设置返回函数,则行为类似于将函数放入单个
LATERAL ROWS FROM( ... )
FROM
项目中所获得的行为.对于基础查询中的每一行,都有一个输出行,使用每个函数的第一个结果,然后是使用第二个结果的输出行,依此类推.如果某些set-returns函数产生的输出少于其他函数,则将null值替换为缺失数据,以便为一个底层行发出的总行数与生成最多输出的set-returns函数相同.因此,set-returns函数以"锁步"方式运行,直到它们全部耗尽,然后继续执行下一个底层行.
这结束了传统上奇怪的行为.
结果行的数量(有点令人惊讶!)是同一列表中所有集合的最低公倍数SELECT
.(只有CROSS JOIN
如果所有设置大小都没有公约数!)演示:
SELECT generate_series( 1, 2) AS row2
, generate_series(11, 13) AS row3
, generate_series(21, 24) AS row4;
Run Code Online (Sandbox Code Playgroud)
row2 | row3 | row4 -----+------+----- 1 | 11 | 21 2 | 12 | 22 1 | 13 | 23 2 | 11 | 24 1 | 12 | 21 2 | 13 | 22 1 | 11 | 23 2 | 12 | 24 1 | 13 | 21 2 | 11 | 22 1 | 12 | 23 2 | 13 | 24
dbfiddle 在这里
记录在手册的Postgres 9.6章SQL函数返回集合与建议,一起避免:
注意:在选择列表而不是
FROM
子句中使用set-returns函数的关键问题是在同一个选择列表中放置多个set-returns函数的行为不是很明智.(如果这样做,实际得到的是一些输出行,它们等于每个set-returns函数产生的行数的最小公倍数.)LATERAL
当调用多个set-returns函数时,语法产生的结果不那么令人惊讶,并且通常应该使用.
大胆强调我的.
单个设置返回功能正常(但在FROM
列表中仍然更清晰),但SELECT
现在不鼓励使用同一列表中的多个.在我们LATERAL
加入之前,这是一个有用的功能.现在它只是历史的镇流器.
有关:
归档时间: |
|
查看次数: |
951 次 |
最近记录: |