Đó là một vấn đề khó hiểu về cách nhiều hàm trả về được thực thi khi được gọi trong SELECT
-danh sách. Bạn mong đợi kết quả là sản phẩm chéo của cả hai, nhưng đó không phải là cách nó hoạt động. Nó thực sự là bội số chung thấp nhất trong số các hàng của cả hai.
Xem:
- Tại sao các kết nối này lại khác nhau dựa trên kích thước?
- Cách viết lại câu lệnh SELECT ... CROSS JOIN LATERAL ... cho các phiên bản PostgreSQL cũ hơn?
So sánh:
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)
Vì lý do này, trên PostgreSQL 9.2 trở lên, bạn nên sử dụng LATERAL
các truy vấn trong đó bạn gọi các hàm set-return trong FROM
mệnh đề:
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)
Trên các phiên bản cũ hơn, bạn có thể sử dụng truy vấn con trong FROM để tránh có nhiều SRF trong một thuật ngữ CHỌN:
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)