Poiché questi tre aggregati provengono dalla stessa tabella con lo stesso WHERE
condizioni, non sono necessarie selezioni secondarie. Tutti e tre gli aggregati operano sullo stesso raggruppamento di righe (nessun GROUP BY
specificato, quindi una riga per l'intera tabella), in modo che possano esistere tutti in SELECT
elenca direttamente.
SELECT
SUM(number) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
Se uno qualsiasi degli aggregati deve essere basato su condizioni diverse, filtri in un WHERE
clausola, quindi sarà necessario utilizzare una sottoselezione per la condizione diversa o eseguire un join cartesiano. Questa sottoselezione e il seguente LEFT JOIN
il metodo dovrebbe essere equivalente, in termini di prestazioni per gli aggregati che restituiscono una sola riga:
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 alla query precedente, puoi LEFT JOIN
contro una sottoquery senza ON
clausola . Questo dovrebbe essere fatto solo in situazioni in cui sai che la sottoquery restituirà solo una riga. Altrimenti, ti ritroverai con un prodotto cartesiano -- tante righe quante sono restituite da un lato del join moltiplicato per il numero di righe restituite dall'altro lato.
Questo è utile se devi restituire alcune colonne con un set di WHERE
condizioni della clausola e alcune colonne con un diverso insieme di WHERE
condizioni, ma solo uno riga da ciascun lato di JOIN
. In questo caso, dovrebbe essere più veloce JOIN
piuttosto che farne due sottoseleziona con lo stesso WHERE
clausola.
Dovrebbe essere più veloce....
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... */
Allora...
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`