Dado que estos tres agregados provienen de la misma tabla con el mismo WHERE
condiciones, no necesita subselecciones. Los tres agregados están operando en la misma agrupación de filas (sin GROUP BY
especificado, por lo que una fila para toda la tabla), por lo que todos pueden existir en el SELECT
lista directamente.
SELECT
SUM(number) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
Si alguno de los agregados debe basarse en diferentes condiciones, filtraría en WHERE
cláusula, entonces deberá usar una subselección para la condición diferente o hacer una unión cartesiana. Esta subselección y la siguiente LEFT JOIN
El método debe ser equivalente, en cuanto al rendimiento, para los agregados que devuelven solo una fila:
SELECT
/* Unique filtering condition - must be done in a subselect */
(SELECT SUM(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
O equivalente a la consulta anterior, puede LEFT JOIN
contra una subconsulta sin ON
cláusula . Esto solo debe hacerse en situaciones en las que sabe que la subconsulta devolverá solo una fila. De lo contrario, terminará con un producto cartesiano:tantas filas como devuelva un lado de la combinación multiplicadas por el número de filas devueltas por el otro lado.
Esto es útil si necesita devolver algunas columnas con un conjunto de WHERE
condiciones de la cláusula y algunas columnas con un conjunto diferente de WHERE
condiciones, pero solo una fila de cada lado de JOIN
. En este caso, debería ser más rápido JOIN
que hacer dos subselecciona con el mismo WHERE
cláusula.
Esto debería ser más rápido....
SELECT
/* this one has two aggregates sharing a WHERE condition */
subq.number_sum_filtered,
subq.number_max_filtered,
/* ...and two aggregates on the main table with no WHERE clause filtering */
MAX(`table`.number) AS number_max,
MIN(`table`.number) AS number_min
FROM
`table`
LEFT JOIN (
SELECT
SUM(number) AS number_sum_filtered,
MAX(number) AS number_max_filtered
FROM `table`
WHERE `somecolumn = `somevalue`
) subq /* No ON clause here since there's no common column to join on... */
Que esto...
SELECT
/* Two different subselects each over the same filtered set */
(SELECT SUM(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_sum_filtered,
(SELECT MAX(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_max_filtered,
MAX(`table`.number) AS number_max,
MIN(`table`.number) AS number_min
FROM
`table`