cul*_*rón 1 postgresql combinations postgis generate-series
我得到了一些组合generate_series的奇怪行为.在我试图用网格填充的2个不同的多边形中,一个网格非常罕见:

查询是这样的:
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;
Run Code Online (Sandbox Code Playgroud)
我试着追踪问题,只输入了最小/最大坐标.从最小值/最大值生成序列创建正确的值数:分别为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)
Run Code Online (Sandbox Code Playgroud)
结合起来,他们应该制作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)
Run Code Online (Sandbox Code Playgroud)
蛮力实际上在这里工作:
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;
Run Code Online (Sandbox Code Playgroud)
制作108排.很好,除了查询变得更复杂.
为什么这样?
Postgres版本是9.1
在SELECT-list中调用时,如何执行多个set-returns函数是一个怪癖.你希望结果是两者的交叉乘积,但这不是它的工作原理.它实际上是两者行数的最低公倍数.
看到:
相比:
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)
Run Code Online (Sandbox Code Playgroud)
因此,在PostgreSQL 9.2及更高版本中,您应该使用LATERAL在FROM子句中调用set-returns函数的查询:
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)
Run Code Online (Sandbox Code Playgroud)
在旧版本中,您可以使用子查询在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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
133 次 |
| 最近记录: |