Da disse tre aggregater kommer fra den samme tabel med den samme WHERE
betingelser, har du ikke behov for undervalg. Alle tre aggregater arbejder på den samme rækkegruppering (ingen GROUP BY
specificeret, så en række for hele tabellen), så de alle kan eksistere i SELECT
liste direkte.
SELECT
SUM(number) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
Hvis nogen af aggregaterne skal være baseret på forskellige betingelser, vil du filtrere i en WHERE
klausul, så skal du enten bruge et undervalg til den afvigende betingelse eller lave en kartesisk joinforbindelse. Dette undervalg og følgende LEFT JOIN
metoden skal være ækvivalent, præstationsmæssigt for aggregater, der kun returnerer én række:
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`
Eller svarende til forespørgslen ovenfor, du kan LEFT JOIN
mod en underforespørgsel uden ON
klausul . Dette bør kun gøres i situationer, hvor du ved, at underforespørgslen kun vil returnere én række. Ellers vil du ende med et kartesisk produkt -- lige så mange rækker, som returneres af den ene side af sammenføjningen multipliceret med antallet af rækker returneret af den anden side.
Dette er praktisk, hvis du har brug for at returnere et par kolonner med ét sæt WHERE
klausulbetingelser og nogle få kolonner med et andet sæt WHERE
betingelser, men kun én række fra hver side af JOIN
. I dette tilfælde burde det være hurtigere at JOIN
end at gøre to undervælger med den samme WHERE
klausul.
Dette burde være hurtigere...
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... */
End dette...
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`