Generalmente, para descomponer filas devuelto de una función y obtiene columnas individuales:
SELECT * FROM account_servicetier_for_day(20424, '2014-08-12');
En cuanto a la consulta:
Postgres 9.3 o posterior
Limpiador con JOIN LATERAL
:
SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
, a.username, a.accountid, a.userid
, f.* -- but avoid duplicate column names!
FROM account_tab a
, account_servicetier_for_day(a.accountid, '2014-08-12') f -- <-- HERE
WHERE a.isdsl = 1
AND a.dslservicetypeid IS NOT NULL
AND NOT EXISTS (
SELECT 1
FROM dailyaccounting_tab
WHERE day = '2014-08-12'
AND accountid = a.accountid
)
ORDER BY a.username;
El LATERAL
La palabra clave está implícita aquí, las funciones siempre pueden referirse a FROM
anteriores. artículos. El manual:
LATERAL
también puede preceder a una llamada de función FROM
elemento, pero en este caso es una palabra irrelevante, porque la expresión de la función puede referirse a un FROM
anterior artículos en cualquier caso.
Relacionado:
- Insertar varias filas en una tabla según el número en otra tabla
Notación abreviada con una coma en FROM
list es (en su mayoría) equivalente a CROSS JOIN LATERAL
(igual que [INNER] JOIN LATERAL ... ON TRUE
) y, por lo tanto, elimina filas del resultado donde la llamada a la función no devuelve ninguna fila. Para conservar dichas filas, utilice LEFT JOIN LATERAL ... ON TRUE
:
...
FROM account_tab a
LEFT JOIN LATERAL account_servicetier_for_day(a.accountid, '2014-08-12') f ON TRUE
...
Además, no use NOT IN (subquery)
cuando puedes evitarlo. Es la forma más lenta y complicada de hacerlo:
- Seleccionar filas que no están presentes en otra tabla
Sugiero NOT EXISTS
en su lugar.
Postgres 9.2 o anterior
Puede llamar a una función de devolución de conjuntos en SELECT
list (que es una extensión de Postgres de SQL estándar). Por motivos de rendimiento, es mejor hacerlo en una subconsulta. Descomponga el tipo de fila (¡bien conocido!) en la consulta externa para evitar la evaluación repetida de la función:
SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
, a.username, a.accountid, a.userid
, (a.rec).* -- but avoid duplicate column names!
FROM (
SELECT *, account_servicetier_for_day(a.accountid, '2014-08-12') AS rec
FROM account_tab a
WHERE a.isdsl = 1
AND a.dslservicetypeid Is Not Null
AND NOT EXISTS (
SELECT 1
FROM dailyaccounting_tab
WHERE day = '2014-08-12'
AND accountid = a.accountid
)
) a
ORDER BY a.username;
Respuesta relacionada de Craig Ringer con una explicación, por qué es mejor descomponer en la consulta externa:
- ¿Cómo evitar múltiples evaluaciones de funciones con la sintaxis (func()).* en una consulta SQL?
Postgres 10 eliminó las rarezas en el comportamiento de las funciones de devolución de conjuntos en SELECT
:
- ¿Cuál es el comportamiento esperado para varias funciones de devolución de conjuntos en la cláusula SELECT?