HAVING句とは、集計した「結果」に対して条件を付けます。
実際に試してみましょう。
確認用にテーブルとデータを用意します。
CREATE TABLE test_table (
id bigint(20) UNSIGNED NOT NULL,
kind int(11) NOT NULL
);
ALTER TABLE `test_table` ADD UNIQUE KEY `id` (`id`);
ALTER TABLE `test_table` MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT;
INSERT INTO `test_table` (`kind`) VALUES ('1');
INSERT INTO `test_table` (`kind`) VALUES ('1');
INSERT INTO `test_table` (`kind`) VALUES ('2');
INSERT INTO `test_table` (`kind`) VALUES ('3');
INSERT INTO `test_table` (`kind`) VALUES ('4');
INSERT INTO `test_table` (`kind`) VALUES ('4');
INSERT INTO `test_table` (`kind`) VALUES ('4');
INSERT INTO `test_table` (`kind`) VALUES ('3');
データを見てみます。
SELECT * FROM test_table;
+----+------+
| id | kind |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
| 5 | 4 |
| 6 | 4 |
| 7 | 4 |
| 8 | 3 |
+----+------+
INSERTした情報がそのまま出てきます。
では、kindで件数を集計します。
SELECT kind, count(kind) as cnt FROM test_table GROUP BY kind;
+------+-----+
| kind | cnt |
+------+-----+
| 1 | 2 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
+------+-----+
kindと集計された件数cntが出てきます。
では、kindが3の列を抽出します。
普通にWHERE句で指定します。
SELECT kind, count(kind) as cnt FROM test_table WHERE kind = 3 GROUP BY kind;
+------+-----+
| kind | cnt |
+------+-----+
| 3 | 2 |
+------+-----+
kindが3の列が普通にヒットします。
では、cntが3の列を抽出します。
先ほどと同様、WHERE句で指定してみます。
SELECT kind, count(kind) as cnt FROM test_table WHERE cnt = 2 GROUP BY kind;
Unknown column 'cnt' in 'where clause'
エラーが出ちまいました。
cntなんてカラムは無いよ、ということです。
これは、WHERE句は集計する前のテーブルのカラムには適用ができないからです。
そこで使えるのがHAVING句です。
集計した「結果」に対して条件を付けます。
SELECT kind, count(kind) as cnt FROM test_table GROUP BY kind HAVING cnt = 2;
+------+-----+
| kind | cnt |
+------+-----+
| 1 | 2 |
| 3 | 2 |
+------+-----+
ちゃんと抽出できました!
やったね!!