Da diese drei Aggregate aus der gleichen Tabelle mit dem gleichen WHERE
Bedingungen haben, brauchen Sie keine Unterauswahlen. Alle drei Aggregate arbeiten mit der gleichen Zeilengruppierung (keine GROUP BY
angegeben, also eine Zeile für die gesamte Tabelle), so dass sie alle in der SELECT
Liste direkt.
SELECT
SUM(number) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
Wenn eines der Aggregate auf verschiedenen Bedingungen basieren muss, würden Sie in einer WHERE
Klausel, dann müssen Sie entweder eine Unterauswahl für die abweichende Bedingung verwenden oder eine kartesische Verknüpfung durchführen. Diese Unterauswahl und die folgende LEFT JOIN
Methode sollte für Aggregate, die nur eine Zeile zurückgeben, leistungsmäßig 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`
Entsprechend der obigen Abfrage können Sie auch LEFT JOIN
gegen eine Unterabfrage ohne ON
Klausel . Dies sollte nur in Situationen geschehen, in denen Sie wissen, dass die Unterabfrage nur eine Zeile zurückgeben wird. Andernfalls erhalten Sie ein kartesisches Produkt - so viele Zeilen, wie eine Seite der Verknüpfung zurückgibt multipliziert mit die Anzahl der von der anderen Seite zurückgegebenen Zeilen.
Dies ist praktisch, wenn Sie mehrere Spalten mit einem Satz von WHERE
Klauselbedingungen und ein paar Spalten mit einem anderen Satz von WHERE
Bedingungen, sondern nur eine Reihe von jeder Seite des JOIN
. In diesem Fall sollte es schneller gehen, wenn JOIN
als zu tun zwei Unterauswahlen mit demselben WHERE
Klausel.
Dies sollte schneller sein....
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... */
Und dann 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`