Ini adalah kekhasan tentang bagaimana beberapa fungsi pengembalian-set dieksekusi ketika dipanggil di SELECT
-daftar. Anda mengharapkan hasilnya menjadi produk silang dari keduanya, tetapi bukan itu cara kerjanya. Ini sebenarnya adalah kelipatan persekutuan terendah dari jumlah baris keduanya.
Lihat:
- Mengapa ini bergabung secara berbeda berdasarkan ukuran?
- Bagaimana cara menulis ulang pernyataan SELECT ... CROSS JOIN LATERAL ... untuk versi PostgreSQL yang lebih lama?
Bandingkan:
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)
Untuk alasan ini, pada PostgreSQL 9.2 dan di atasnya Anda harus menggunakan LATERAL
kueri tempat Anda menjalankan fungsi pengembalian set di FROM
klausa:
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)
Pada versi yang lebih lama, Anda dapat menggunakan subquery-in-FROM untuk menghindari beberapa SRF dalam istilah SELECT:
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)