Det er et særpræg af, hvordan flere sæt-returnerende funktioner udføres, når de aktiveres i SELECT
-liste. Man forventer, at resultatet er krydsproduktet af de to, men sådan fungerer det ikke. Det er faktisk det laveste fælles multiplum af rækkeantallet af de to.
Se:
- Hvorfor forbindes disse forskelligt baseret på størrelse?
- Hvordan omskriver man en SELECT ... CROSS JOIN LATERAL ...-erklæring til ældre PostgreSQL-versioner?
Sammenlign:
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)
Af denne grund bør du på PostgreSQL 9.2 og nyere bruge LATERAL
forespørgsler, hvor du aktiverer sæt-returnerende funktioner i FROM
klausul:
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)
På ældre versioner kan du bruge en underforespørgsel-i-FROM for at undgå at have flere SRF'er i et SELECT-udtryk:
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)