自分で作成した列 (例select 1 as "number"
) をMySQL ではHAVING
なく の後に配置する必要があるのはなぜですか?WHERE
WHERE 1
また、列名の代わりに定義全体を記述する代わりに、何か欠点はありますか?
ベストアンサー1
この質問に対する他のすべての回答は、重要な点に触れていませんでした。
次のテーブルがあると仮定します。
CREATE TABLE `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`value` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `value` (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
そして、ID と値が 1 から 10 までである 10 行があります。
INSERT INTO `table`(`id`, `value`) VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(10, 10);
次の 2 つのクエリを試してください。
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
HAVING
まったく同じ結果が得られ、 GROUP BY 句がなくても句が機能することがわかります。
違いは次のとおりです。
SELECT `value` v FROM `table` WHERE `v`>5;
上記のクエリはエラーを発生させます: エラー #1054 - 'where 句' に不明な列 'v' があります
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
WHERE
句では、条件で任意のテーブル列を使用できますが、別名や集計関数は使用できません。HAVING
句では、条件で選択した (!) 列、別名、または集計関数を使用できます。
WHERE
これは、句が選択前にデータをフィルタリングしますが、HAVING
句が選択後に結果データをフィルタリングするためです。
WHERE
したがって、テーブルに多数の行がある場合は、条件句を指定するとより効率的になります。
EXPLAIN
主な違いを見てみましょう:
EXPLAIN SELECT `value` v FROM `table` WHERE `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| 1 | SIMPLE | table | range | value | value | 4 | NULL | 5 | Using where; Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
EXPLAIN SELECT `value` v FROM `table` having `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| 1 | SIMPLE | table | index | NULL | value | 4 | NULL | 10 | Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
WHERE
またはがインデックスを使用していることがわかりますHAVING
が、行は異なります。