これらの3つの集計は、同じWHERE
の同じテーブルからのものであるため 条件では、副選択は必要ありません。 3つのアグリゲートはすべて、同じ行グループで動作しています(GROUP BY
はありません) 指定されているため、テーブル全体に対して1行)、すべてがSELECT
に存在できるようにします。 直接リストします。
SELECT
SUM(number) AS number_sum,
MAX(number) AS number_max,
MIN(number) AS number_min
FROM `table`
集計のいずれかをさまざまな条件に基づく必要がある場合は、WHERE
でフィルタリングします 句の場合、異なる条件に対して副選択を使用するか、デカルト結合を実行する必要があります。この副選択と次のLEFT JOIN
メソッドは、1つの行のみを返す集計の場合、パフォーマンス的に同等である必要があります。
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`
または、上記のクエリと同等に、LEFT JOIN
を実行できます。 ON
のないサブクエリに対して 条項 。これは、サブクエリが1行のみを返すことがわかっている状況でのみ実行する必要があります。そうしないと、デカルト積になってしまいます。つまり、結合の片側から返される行の数を乗算します。 反対側から返された行の数。
これは、1セットのWHERE
でいくつかの列を返す必要がある場合に便利です。 句の条件と、WHERE
のセットが異なるいくつかの列 条件、ただし1つのみ JOIN
の両側からの行 。この場合、JOIN
の方が速いはずです 2つを行うよりも 同じWHERE
で副選択します 条項。
これはもっと速いはずです....
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... */
これより...
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`