Karena ketiga agregat ini berasal dari tabel yang sama dengan WHERE
yang sama kondisi, Anda tidak memerlukan subpilihan. Ketiga agregat beroperasi pada pengelompokan baris yang sama (tidak ada GROUP BY
ditentukan, jadi satu baris untuk seluruh tabel), sehingga semuanya bisa ada di SELECT
daftar langsung.
SELECT
SUM(number) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
Jika salah satu agregat perlu didasarkan pada kondisi yang berbeda, Anda akan memfilter dalam WHERE
klausa, maka Anda harus menggunakan subselect untuk kondisi yang berbeda, atau melakukan cartesian join. Subpilih ini dan LEFT JOIN
berikut ini metode harus setara, dari segi kinerja untuk agregat yang hanya mengembalikan satu baris:
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`
Atau setara dengan query di atas, Anda bisa LEFT JOIN
terhadap subquery tanpa ON
klausa . Ini hanya boleh dilakukan dalam situasi ketika Anda tahu subquery hanya akan mengembalikan satu baris. Jika tidak, Anda akan mendapatkan produk kartesius -- sebanyak baris yang dikembalikan oleh satu sisi gabungan dikalikan jumlah baris yang dikembalikan oleh sisi lain.
Ini berguna jika Anda perlu mengembalikan beberapa kolom dengan satu set WHERE
kondisi klausa dan beberapa kolom dengan kumpulan WHERE
yang berbeda kondisi, tetapi hanya satu baris dari setiap sisi JOIN
. Dalam hal ini, seharusnya lebih cepat untuk JOIN
daripada melakukan dua subpilihan dengan WHERE
yang sama klausa.
Ini seharusnya lebih cepat....
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... */
Dari pada ini...
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`