Това е странност за това как се изпълняват множество връщащи набор функции, когато се извикват в SELECT
- списък. Очаквате резултатът да бъде кръстосано произведение на двете, но не работи така. Това всъщност е най-малкото общо кратно на броя на редовете на двете.
Вижте:
- Защо тези се съединяват по различен начин в зависимост от размера?
- Как да пренапиша оператор SELECT ... CROSS JOIN LATERAL ... за по-стари версии на PostgreSQL?
Сравнете:
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)
Поради тази причина на PostgreSQL 9.2 и по-нови трябва да използвате LATERAL
заявки, при които извиквате функции за връщане на набор в FROM
клауза:
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-FROM, за да избегнете наличието на множество SRF в термин 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)