Da diese drei Aggregate aus derselben Tabelle mit demselben WHERE
stammen Bedingungen benötigen Sie keine Unterauswahlen. Alle drei Aggregate arbeiten mit derselben Zeilengruppierung (kein GROUP BY
angegeben, also eine Zeile für die ganze Tabelle), damit sie alle im SELECT
existieren können direkt auflisten.
SELECT
SUM(number) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
Wenn eines der Aggregate auf anderen Bedingungen basieren muss, würden Sie in einem WHERE
filtern -Klausel, dann müssen Sie entweder eine Unterauswahl für die abweichende Bedingung verwenden oder eine kartesische Verknüpfung durchführen. Diese Unterauswahl und das folgende LEFT JOIN
-Methode sollte hinsichtlich der Leistung für Aggregate, die nur eine Zeile zurückgeben, gleichwertig sein:
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`
Oder äquivalent zur obigen Abfrage können Sie LEFT JOIN
gegen eine Unterabfrage ohne ON
Klausel . Dies sollte nur in Situationen erfolgen, in denen Sie wissen, dass die Unterabfrage nur eine Zeile zurückgibt. Andernfalls erhalten Sie ein kartesisches Produkt – so viele Zeilen, wie von einer Seite des Joins multipliziert mit zurückgegeben werden die Anzahl der von der anderen Seite zurückgegebenen Zeilen.
Dies ist praktisch, wenn Sie einige Spalten mit einem Satz von WHERE
zurückgeben müssen Klauselbedingungen und ein paar Spalten mit einem anderen Satz von WHERE
Bedingungen, aber nur eine Reihe von jeder Seite des JOIN
. In diesem Fall sollte JOIN
schneller sein als zwei zu tun Unterauswahlen mit demselben WHERE
Klausel.
Das sollte schneller gehen....
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... */
Als das...
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`