sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cuál es el comportamiento esperado para múltiples funciones de devolución de conjuntos en la cláusula SELECT?

Postgres 10 o posterior

agrega valores nulos para conjuntos más pequeños. Demostración con generate_series() :

SELECT generate_series( 1,  2) AS row2
     , generate_series(11, 13) AS row3
     , generate_series(21, 24) AS row4;
row2 | row3 | row4
-----+------+-----
   1 |   11 |   21
   2 |   12 |   22
null |   13 |   23
null | null |   24

dbfiddle aquí

El manual para Postgres 10 :

Si hay más de una función de devolución de conjuntos en la lista de selección de la consulta, el comportamiento es similar al que se obtiene al colocar las funciones en un solo LATERAL ROWS FROM( ... ) FROM -artículo de cláusula. Para cada fila de la consulta subyacente, hay una fila de salida que usa el primer resultado de cada función, luego una fila de salida que usa el segundo resultado, y así sucesivamente. Si algunas de las funciones que devuelven conjuntos producen menos salidas que otras, los datos que faltan se sustituyen por valores nulos, de modo que el número total de filas emitidas para una fila subyacente es el mismo que para la función de devolución de conjuntos que produjo la mayoría de las salidas. Por lo tanto, las funciones de devolución de conjuntos se ejecutan "a la par" hasta que se agotan todas, y luego la ejecución continúa con la siguiente fila subyacente.

Esto pone fin al comportamiento tradicionalmente extraño.

Postgres 9.6 o anterior

El número de filas de resultados (¡algo sorprendente!) es el mínimo común múltiplo de todos los conjuntos en el mismo SELECT lista. (Solo actúa como un CROSS JOIN si no hay un divisor común para todos los tamaños de conjuntos!) Demostración:

SELECT generate_series( 1,  2) AS row2
     , generate_series(11, 13) AS row3
     , generate_series(21, 24) AS row4;
row2 | row3 | row4
-----+------+-----
   1 |   11 |   21
   2 |   12 |   22
   1 |   13 |   23
   2 |   11 |   24
   1 |   12 |   21
   2 |   13 |   22
   1 |   11 |   23
   2 |   12 |   24
   1 |   13 |   21
   2 |   11 |   22
   1 |   12 |   23
   2 |   13 |   24

dbfiddle aquí

Documentado en manual para Postgres 9.6 el capítulo Funciones SQL que devuelven conjuntos , junto con la recomendación para evitarlo:

Nota:El problema clave con el uso de funciones de devolución de conjuntos en la lista de selección, en lugar de FROM cláusula, es que poner más de una función que devuelve un conjunto en la misma lista de selección no se comporta de manera muy sensata. (Lo que realmente obtiene si lo hace es una cantidad de filas de salida igual al mínimo común múltiplo de la cantidad de filas producidas por cada función de devolución de conjuntos. ) El LATERAL La sintaxis produce resultados menos sorprendentes al llamar a varias funciones de devolución de conjuntos y, por lo general, debe usarse en su lugar.

Énfasis en negrita mío.

Una sola función de devolución de conjuntos está bien (pero aún más limpia en el FROM list), pero múltiples en el mismo SELECT la lista está desaconsejada ahora. Esta fue una función útil antes de que tuviéramos LATERAL Uniones. Ahora es simplemente un lastre histórico.

Relacionado:

  • Unnest() paralelo y orden de clasificación en PostgreSQL
  • Desanime varios arreglos en paralelo
  • ¿Cuál es la diferencia entre LATERAL JOIN y una subconsulta en PostgreSQL?