Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 为什么这些连接会根据大小而有所不同?_Arrays_Postgresql - Fatal编程技术网

Arrays 为什么这些连接会根据大小而有所不同?

Arrays 为什么这些连接会根据大小而有所不同?,arrays,postgresql,Arrays,Postgresql,在Postgresql中,如果取消嵌套两个大小相同的数组,它们会将一个数组中的每个值与另一个数组中的每个值对齐,但如果两个数组的大小不同,它会将一个数组中的每个值与另一个数组中的每个值合并 select unnest(ARRAY[1, 2, 3, 4, 5]::bigint[]) as id, unnest(ARRAY['a', 'b', 'c', 'd', 'e']) as value 会回来的 1 | "a" 2 | "b" 3 | "c" 4 | "d" 5 | "e" 1 | "a"

在Postgresql中,如果取消嵌套两个大小相同的数组,它们会将一个数组中的每个值与另一个数组中的每个值对齐,但如果两个数组的大小不同,它会将一个数组中的每个值与另一个数组中的每个值合并

select unnest(ARRAY[1, 2, 3, 4, 5]::bigint[]) as id,
unnest(ARRAY['a', 'b', 'c', 'd', 'e']) as value
会回来的

1 | "a"
2 | "b"
3 | "c"
4 | "d"
5 | "e"
1 | "a"
1 | "b"
1 | "c"
1 | "d"
2 | "b"
2 | "a"
2 | "c"
2 | "d"
3 | "b"
3 | "d"
3 | "a"
3 | "c"
4 | "d"
4 | "a"
4 | "c"
4 | "b"
5 | "d"
5 | "c"
5 | "b"
5 | "a"
但是

会回来的

1 | "a"
2 | "b"
3 | "c"
4 | "d"
5 | "e"
1 | "a"
1 | "b"
1 | "c"
1 | "d"
2 | "b"
2 | "a"
2 | "c"
2 | "d"
3 | "b"
3 | "d"
3 | "a"
3 | "c"
4 | "d"
4 | "a"
4 | "c"
4 | "b"
5 | "d"
5 | "c"
5 | "b"
5 | "a"

为什么会这样?我假设正在使用某种隐式规则,我想知道我是否可以显式地这样做(例如,当我有匹配的数组大小时,我是否希望使用第二种样式,或者我是否希望将一个数组中缺少的值视为NULL)。

SELECT
中支持集合返回函数是一个PostgreSQL扩展,而且是一个非常奇怪的扩展。人们普遍认为它已被弃用,最好尽可能避免使用

尽可能避免在-
选择中使用SRF
既然9.3中支持了
LATERAL
,两个主要用途之一就消失了。如果您想将一个SRF的输出用作另一个SRF的输入,则必须在
SELECT
中使用设置返回功能;横向
不再需要此功能

在9.4中,当添加带有顺序性的
时,另一个用法将被替换,允许您保留集合返回函数的输出顺序。这是目前剩下的主要用途:将两个SRF的输出压缩到匹配值对的行集中<对于
unnest
,最需要的是带有有序性的code>,但可用于任何其他SRF

为什么会有奇怪的输出? PostgreSQL在这里使用的逻辑(无论出于什么疯狂的原因,它最初是在古代历史中引入的)是:无论何时任一函数产生输出,都会发出一行。如果只有一个函数生成了输出,请再次扫描另一个函数的输出以获得所需的行。如果两者都不产生输出,则停止发射行

使用
generate_series
更容易查看

regress=> SELECT generate_series(1,2), generate_series(1,2);
 generate_series | generate_series 
-----------------+-----------------
               1 |               1
               2 |               2
(2 rows)

regress=> SELECT generate_series(1,2), generate_series(1,3);
 generate_series | generate_series 
-----------------+-----------------
               1 |               1
               2 |               2
               1 |               3
               2 |               1
               1 |               2
               2 |               3
(6 rows)

regress=> SELECT generate_series(1,2), generate_series(1,4);
 generate_series | generate_series 
-----------------+-----------------
               1 |               1
               2 |               2
               1 |               3
               2 |               4
(4 rows)
在大多数情况下,您真正想要的是两者的简单交叉连接,这要明智得多

regress=> SELECT a, b FROM generate_series(1,2) a, generate_series(1,2) b;
 a | b 
---+---
 1 | 1
 1 | 2
 2 | 1
 2 | 2
(4 rows)

regress=> SELECT a, b FROM generate_series(1,2) a, generate_series(1,3) b;
 a | b 
---+---
 1 | 1
 1 | 2
 1 | 3
 2 | 1
 2 | 2
 2 | 3
(6 rows)

regress=> SELECT a, b FROM generate_series(1,2) a, generate_series(1,4) b;
 a | b 
---+---
 1 | 1
 1 | 2
 1 | 3
 1 | 4
 2 | 1
 2 | 2
 2 | 3
 2 | 4
(8 rows)
当前的主要例外情况是,当您希望在锁定步骤中成对运行多个函数时(如
zip
),这是您当前无法使用联接执行的

具有顺序性
这将在9.4中通过使用
和来改进,虽然它的效率比SELECT中的多个SRF扫描要低一些(除非添加了优化器改进),但它将更加稳健

regress=> SELECT a, b FROM generate_series(1,2) a, generate_series(1,2) b;
 a | b 
---+---
 1 | 1
 1 | 2
 2 | 1
 2 | 2
(4 rows)

regress=> SELECT a, b FROM generate_series(1,2) a, generate_series(1,3) b;
 a | b 
---+---
 1 | 1
 1 | 2
 1 | 3
 2 | 1
 2 | 2
 2 | 3
(6 rows)

regress=> SELECT a, b FROM generate_series(1,2) a, generate_series(1,4) b;
 a | b 
---+---
 1 | 1
 1 | 2
 1 | 3
 1 | 4
 2 | 1
 2 | 2
 2 | 3
 2 | 4
(8 rows)
假设您想将
1..3
10..40
与多余元素的空值配对。使用带有有序性的
(仅限PostgreSQL 9.4):

当来自的srf返回时:

regress=# SELECT generate_series(1,3) aval, generate_series(1,4) bval;
 aval | bval 
------+------
    1 |    1
    2 |    2
    3 |    3
    1 |    4
    2 |    1
    3 |    2
    1 |    3
    2 |    4
    3 |    1
    1 |    2
    2 |    3
    3 |    4
(12 rows)

值得一提的是,
LATERAL
在这里是隐式的,特别是因为本例不使用其他from子句中的术语,因为LATERAL允许。另外,在添加侧向力之前,您可以将srf作为from子句,对吗?