Aangezien deze drie aggregaten uit dezelfde tabel komen met dezelfde WHERE
voorwaarden, hebt u geen subselecties nodig. Alle drie de aggregaten werken op dezelfde rijgroepering (geen GROUP BY
opgegeven, dus één rij voor de hele tabel), zodat ze allemaal kunnen bestaan in de SELECT
lijst direct.
SELECT
SUM(number) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
Als een van de aggregaten op verschillende voorwaarden moet worden gebaseerd, filtert u in een WHERE
clausule, dan moet u ofwel een subselect gebruiken voor de verschillende voorwaarde, of een cartesische join uitvoeren. Deze subselectie en de volgende LEFT JOIN
methode moet qua prestaties gelijkwaardig zijn voor aggregaten die slechts één rij retourneren:
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`
Of gelijkwaardig aan de bovenstaande zoekopdracht, u kunt LEFT JOIN
tegen een subquery zonder ON
clausule . Dit moet alleen worden gedaan in situaties waarin u weet dat de subquery slechts één rij retourneert. Anders krijg je een cartesiaans product -- zoveel rijen als geretourneerd met één zijde van de join vermenigvuldigd met het aantal rijen dat door de andere kant wordt geretourneerd.
Dit is handig als u een paar kolommen moet retourneren met één set WHERE
clausulevoorwaarden en een paar kolommen met een andere set van WHERE
voorwaarden, maar slechts één rij vanaf elke kant van de JOIN
. In dit geval zou het sneller moeten zijn om JOIN
dan om twee te doen subselecteert met dezelfde WHERE
clausule.
Dit zou sneller moeten zijn....
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... */
Dan dit...
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`