Para obtener el resultado sin subconsulta , tienes que recurrir al truco de la función de ventana avanzada:
SELECT sum(count(*)) OVER () AS tickets_count
, sum(min(a.revenue)) OVER () AS atendees_revenue
FROM tickets t
JOIN attendees a ON a.id = t.attendee_id
GROUP BY t.attendee_id
LIMIT 1;
sqlfiddle
¿Cómo funciona?
La clave para entender esto es la secuencia de eventos en la consulta:
funciones agregadas -> funciones de ventana -> DISTINTO -> LÍMITE
Más detalles:
- La mejor manera de obtener el recuento de resultados antes de aplicar LIMIT
Paso a paso:
-
Yo
GROUP BY t.attendee_id
- lo que normalmente haría en una subconsulta. -
Luego sumo los conteos para obtener el conteo total de boletos. No muy eficiente, pero obligado por su requerimiento. La función agregada
count(*)
está envuelto en la función de ventanasum( ... ) OVER ()
para llegar a la expresión no tan común:sum(count(*)) OVER ()
.Y sume los ingresos mínimos por asistente para obtener la suma sin duplicados.
También puedes usar
max()
oavg()
en lugar demin()
con el mismo efecto querevenue
se garantiza que será el mismo para cada fila por asistente.Esto podría ser más simple si
DISTINCT
estaba permitido en las funciones de ventana, pero PostgreSQL (todavía) no ha implementado esta función. Por documentación:Las funciones de ventana agregadas, a diferencia de las funciones agregadas normales, no permiten
DISTINCT
oORDER BY
para ser utilizado dentro de la lista de argumentos de la función. -
El paso final es obtener una sola fila. Esto podría hacerse con
DISTINCT
(estándar SQL) ya que todas las filas son iguales.LIMIT 1
aunque será más rápido. O el formulario estándar de SQLFETCH FIRST 1 ROWS ONLY
.