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?