gpt4 book ai didi

postgresql - 为什么 PostgreSQL 以错误的方式组合系列?

转载 作者:行者123 更新时间:2023-11-29 12:28:28 27 4
gpt4 key购买 nike

我得到了组合 generate_series 的一些奇怪行为。在我尝试用网格填充的 2 个不同的多边形中,一个网格要少得多:

enter image description here

查询是这样的:

SELECT
osm_id ,
generate_series(floor(st_xmin(way))::int, ceiling(st_xmax(way))::int, 150) x,
generate_series(floor(st_ymin(way))::int, ceiling(st_ymax(way))::int, 150) y
from osm_polygon
order by osm_id, x, y;

我尝试追踪问题,只是输入了最小/最大坐标。从最小值/最大值生成系列创建正确数量的值:分别为 9 行和 12 行。

  => select generate_series(9237195, 9238873, 150) x;
x
---------
9237195
9237345
9237495
9237645
9237795
9237945
9238095
9238245
9238395
9238545
9238695
9238845
(12 rows)

=> select generate_series(7371701, 7372922, 150) y order by y;
y
---------
7371701
7371851
7372001
7372151
7372301
7372451
7372601
7372751
7372901
(9 rows)

它们加起来应该有 108 行,对吧?不,只有 36 行:

=> select generate_series(9237195, 9238873, 150) x, generate_series(7371701, 7372922, 150) y order by x, y;
x | y
---------+---------
9237195 | 7371701
9237195 | 7372151
9237195 | 7372601
9237345 | 7371851
9237345 | 7372301
9237345 | 7372751
9237495 | 7372001
9237495 | 7372451
9237495 | 7372901
9237645 | 7371701
9237645 | 7372151
9237645 | 7372601
9237795 | 7371851
9237795 | 7372301
9237795 | 7372751
9237945 | 7372001
9237945 | 7372451
9237945 | 7372901
9238095 | 7371701
9238095 | 7372151
9238095 | 7372601
9238245 | 7371851
9238245 | 7372301
9238245 | 7372751
9238395 | 7372001
9238395 | 7372451
9238395 | 7372901
9238545 | 7371701
9238545 | 7372151
9238545 | 7372601
9238695 | 7371851
9238695 | 7372301
9238695 | 7372751
9238845 | 7372001
9238845 | 7372451
9238845 | 7372901
(36 rows)

蛮力实际上在这里起作用:

with a as (select generate_series(9237195, 9238873, 150) x),
b as (select generate_series(7371701, 7372922, 150) y)
select x, y from a, b;

生成 108 行。很好,只是查询变得更复杂。

为什么会这样?

Postgres 版本是 9.1

最佳答案

这是在 SELECT 列表中调用时如何执行多个设置返回函数的怪癖。您希望结果是两者的叉积,但事实并非如此。它实际上是两者行数的最小公倍数。

参见:

比较:

test=>     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)

test=> SELECT generate_series(1,3) aval, generate_series(1,3) bval;
aval | bval
------+------
1 | 1
2 | 2
3 | 3
(3 rows)

因此,在 PostgreSQL 9.2 及更高版本上,您应该使用 LATERAL 查询,其中您在 FROM 子句中调用集合返回函数:

test=>     SELECT aval, bval FROM generate_series(1,3) aval CROSS JOIN LATERAL generate_series(1,3) bval;
aval | bval
------+------
1 | 1
1 | 2
1 | 3
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
3 | 3
(9 rows)

test=> SELECT aval, bval FROM generate_series(1,3) aval CROSS JOIN LATERAL generate_series(1,4) bval;
aval | bval
------+------
1 | 1
1 | 2
1 | 3
1 | 4
2 | 1
2 | 2
2 | 3
2 | 4
3 | 1
3 | 2
3 | 3
3 | 4
(12 rows)

在旧版本上,您可以使用 FROM 中的子查询来避免在 SELECT 术语中有多个 SRF:

test=> SELECT generate_series(1,3) aval, bval FROM (SELECT generate_series(1,4)) AS x(bval);
aval | bval
------+------
1 | 1
2 | 1
3 | 1
1 | 2
2 | 2
3 | 2
1 | 3
2 | 3
3 | 3
1 | 4
2 | 4
3 | 4
(12 rows)

关于postgresql - 为什么 PostgreSQL 以错误的方式组合系列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31202501/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com