返したいのがすべての重複の合計「カウント」であるが、APPROVEDとCREATED_ATに指定された述語を持つ2つ以上の行を持つ組織NAMESの場合のみ、代替ステートメントを使用して同等のものを返すことができます。結果:
SELECT SUM(c.cnt)
FROM ( SELECT COUNT(organization.ID) AS cnt
FROM organization o
WHERE o.NAME <> ''
GROUP
BY o.NAME
HAVING SUM(o.APPROVED = 0 AND o.CREATED_AT > '2012-07-31 04:31:08') > 1
) c
MySQLは、このクエリを満たすために適切なカバーインデックスを利用できます。そうでない場合、これは組織テーブルのフルスキャンである可能性があります。ただし、組織テーブルを2回参照することは避け、JOIN操作を避けます。
このクエリに適したカバーインデックスの1つは、次のとおりです。
ON organization (NAME, CREATED_AT, APPROVED, ID)
列が非NULLであることが保証されている場合ID
(NOT NULL制約またはテーブルの主キーのいずれかである場合は、その列の参照を回避でき、その列をインデックス定義から除外できます)。
SELECT SUM(c.cnt)
FROM ( SELECT SUM(1) AS cnt
FROM organization o
WHERE o.NAME <> ''
GROUP
BY o.NAME
HAVING SUM(o.APPROVED = 0 AND o.CREATED_AT > '2012-07-31 04:31:08') > 1
) c
EXPLAIN出力は、インデックスを使用してこのクエリを表示し、テーブルのデータブロックを参照せずにクエリを満たします。
id select_type table type possible_keys key key_len ref rows Extra
-- ----------- ---------- ------ --------------- --------------- ------- ------ ------ --------------------------
1 PRIMARY <derived2> ALL (NULL) (NULL) (NULL) (NULL) 2
2 DERIVED o index organization_ix organization_ix 44 (NULL) 29 Using where; Using index