Es ist eine Eigenart, wie mehrere Set-zurückgebende Funktionen ausgeführt werden, wenn sie in SELECT
aufgerufen werden -aufführen. Sie erwarten, dass das Ergebnis das Kreuzprodukt der beiden ist, aber so funktioniert es nicht. Es ist tatsächlich das kleinste gemeinsame Vielfache der Zeilenanzahl der beiden.
Siehe:
- Warum verbinden sich diese je nach Größe unterschiedlich?
- Wie schreibe ich eine SELECT ... CROSS JOIN LATERAL ... -Anweisung für ältere PostgreSQL-Versionen um?
Vergleichen Sie:
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)
Aus diesem Grund sollten Sie unter PostgreSQL 9.2 und höher LATERAL
verwenden Abfragen, bei denen Sie mengenzurückgebende Funktionen im FROM
aufrufen Klausel:
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)
In älteren Versionen können Sie eine Unterabfrage-in-FROM verwenden, um mehrere SRFs in einem SELECT-Begriff zu vermeiden:
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)