260

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

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

4

7 に答える 7

334

MySQLのWHEREではなく、HAVINGの後に自分で作成した列(たとえば、「数値として1を選択」)を配置する必要があるのはなぜですか?

WHEREの前GROUP BYHAVING適用され、後に適用されます(そして集計でフィルタリングできます)。

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

また、「WHERE 1」(列名の代わりに定義全体を記述する)を実行する代わりに、欠点はありますか?

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

于 2010-05-25T13:59:45.857 に答える
324

この質問に対する他のすべての回答は、重要なポイントに当てはまりませんでした。

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

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句はGROUPBY句なしでも機能することがわかります。


違いは次のとおりです。

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

于 2013-09-10T04:30:35.897 に答える
65

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

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

于 2010-05-25T14:00:56.443 に答える
41

HAVINGの集計をフィルタリングするために使用されますGROUP BY

たとえば、重複する名前を確認するには、次のようにします。

SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
于 2010-05-25T14:01:56.590 に答える
10

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

例:テーブルStudentにstudent_id、name、birthday、addressを含めるようにします。birthdayのタイプがdateであると想定します。

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.*/
于 2015-06-21T12:03:43.283 に答える
3

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

そして続けて、

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

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

于 2018-01-05T11:56:50.467 に答える
1

持つことは集約でのみ使用されますが、非集約ステートメントではどこで使用されますか?単語が集約の前にそれを置く場所がある場合(group by)

于 2015-11-09T19:22:17.307 に答える