どこで持つか


247

MySQL内ではなく、自分で作成した列を(たとえばselect 1 as "number")後に配置する必要があるのはなぜですか?HAVINGWHERE

そしてWHERE 1、(列名の代わりに定義全体を書く)代わりに何か欠点がありますか?

回答:


323

MySQLのWHEREではなくHAVINGの後に、自分で作成した列(「select 1 as number」など)を配置する必要があるのはなぜですか?

WHEREGROUP BY、の前にHAVING適用され、後に適用されます(および集計でフィルタリングできます)。

一般に、これらの句のどちらでもエイリアスを参照することはできますが、およびでレベルエイリアスをMySQL参照できます。SELECTGROUP BYORDER BYHAVING

そして、「WHERE 1」を実行する代わりに欠点があります(列名の代わりに定義全体を書き込みます)

計算式に集計が含まれていない場合は、それをWHERE句に入れる方が効率的です。


289

この質問に対する他のすべての回答は、要点に当てはまりませんでした。

テーブルがあると仮定します。

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がインデックスを使用していることがわかりますが、行は異なります。


32
EXPLAINについて言及していただきありがとうございます。
2013

HAVING句は選択後にデータをフィルタリングするため、WHERE句の方が効果的です。これが本当なら、いつWHEREではなくHAVINGを使用する必要があるのでしょうか。
grep

5
@grep選択後にデータをフィルタリングする必要がある場合は、HAVING句が必要です。通常、これをGROUP BY句とともに使用します。例: SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
Fishdrowned

1
素晴らしいポスト。提案の明確化のカップル:変更...HAVING clause can use both column and alias....HAVING clause can use either column or alias.と変更...WHERE clause will be more effective...WHERE clause will be more efficient
rmir​​abelle

2
WHEREキーワードを集約関数で使用できなかったため、HAVING句がSQLに追加されました。
Shashank Vivek

62

主な違いは、WHEREグループ化されたアイテム(などSUM(number))では使用できませんが、使用HAVINGできることです。

その理由は、グループ化のに行わ、グループ化が行われた後にWHERE行われるためです。HAVING



8

これらの2つは、データをフィルタリングするための条件について言うために使用されるため、最初と同じように感じられます。どのような場合でも「where」の代わりに「having」を使用できますが、「having」の代わりに「where」を使用できない場合があります。これは、選択クエリでは、「where」は「select」の前にデータをフィルタリングし、「haven」は「select」の後にデータをフィルタリングするためです。したがって、実際にはデータベースにないエイリアス名を使用する場合、「where」はそれらを識別できませんが、「having」は識別できます。

例:テーブルStudentに、student_id、name、birthday、addressを含めます。誕生日のタイプは日付です。

SELECT * FROM Student WHERE YEAR(birthday)>1993; /*this will work as birthday is in database.if we use having in place of where too this will work*/

SELECT student_id,(YEAR(CurDate())-YEAR(birthday)) AS Age FROM Student HAVING Age>20; 
/*this will not work if we use ‘where’ here, ‘where’ don’t know about age as age is defined in select part.*/

1
完全にこの現実の生活の例の明確化との違いWHEREHAVING
WM

持つことと場所の違いをはっきりと示しています。ありがとう。
MarcoZen

3

WHEREは、データがグループ化される前にフィルタリングし、HAVINGは、データがグループ化された後にフィルタリングします。これは重要な違いです。WHERE句によって削除された行はグループに含まれません。これにより、計算された値が変更され、その結果(=結果として)、HAVING 句でのそれらの値の使用に基づいてフィルタリングされるグループに影響を与える可能性があります。

そして続けます

HAVINGWHEREに非常に似ているため、GROUP BYが指定されていない場合、ほとんどのDBMSはそれらを同じものとして扱います。それでも、自分で区別する必要があります。HAVINGは、GROUP BY 句と組み合わせてのみ使用してください。標準の行レベルのフィルタリングにはWHEREを使用します。

抜粋: フォルタ、ベン。「Sams Teach Yourself SQL in 10 Minutes(5th Edition)(Sams Teach Yourself ...)」。


1

持つことは集約でのみ使用されますが、非集約ステートメントで使用されます単語が集約の前に配置される場合(グループ化)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.