어디에 vs HAVING


247

당신이 장소 컬럼에 필요합니까 왜 당신은 자신 (예를 들어 작성 select 1 as "number") 후 HAVING가 아니라 WHEREMySQL은을?

그리고 WHERE 1대신 열 이름 대신 전체 정의를 작성하는 대신 단점이 있습니까?

답변:


323

MySQL에서 WHERE가 아닌 HAVING 후에 직접 생성 한 열 (예 : "1을 숫자로 선택")을 배치해야하는 이유는 무엇입니까?

WHERE이전 GROUP BYHAVING적용되고 이후에 적용되며 집계를 필터링 할 수 있습니다.

일반적으로,이 조항의도에 별칭을 참조 할 수 있지만, MySQL참조 허용 SELECT에 수준의 별칭을 GROUP BY, ORDER BY그리고 HAVING.

"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

그리고 1과 10 사이의 id와 값을 가진 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);

다음 두 가지 쿼리를 시도하십시오.

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 절은 select 전에 데이터를 필터링하지만 HAVING 절은 select 후 결과 데이터를 필터링하기 때문입니다.

따라서 테이블에 많은 행이있는 경우 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이 index를 사용하는 것을 볼 수 있지만 행이 다릅니다.


32
EXPLAIN을 언급 해 주셔서 감사합니다.
paiego

HAVING 절은 select 후에 데이터를 필터링하기 때문에 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
rmirabelle

2
WHERE 키워드를 집계 함수와 함께 사용할 수 없으므로 HAVING 절이 SQL에 추가되었습니다.
Shashank Vivek

62

주요 차이점은이 WHERE(예를 들면 분류 품목에 사용될 수 SUM(number)있는 반면) HAVING캔.

그 이유는 그룹화 전에WHERE 수행 되고 그룹화 가 완료된 후에 수행 되기 때문입니다 .HAVING



8

이 2는 데이터를 필터링하는 조건에 대해 말하는 데 처음 사용되는 것과 같습니다. 어쨌든 'where'대신 'having'을 사용할 수 있지만 'having'대신 'where'를 사용할 수없는 경우가 있습니다. 선택 쿼리에서 'where'는 'select'뒤에 데이터를 필터링하고 'select'뒤에 필터 데이터를 '갖고'있기 때문입니다. 따라서 실제로 데이터베이스에없는 별칭 이름을 사용할 경우 'where'는 별칭을 식별 할 수 없지만 'having'은 식별 할 수 있습니다.

예 : Student 테이블에 student_id, name, birthday, address를 포함 시키십시오. birthday가 날짜 유형이라고 가정하십시오.

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 를 사용하십시오 .

발췌 : Forta, Ben. “샘은 10 분 (5 판)에 SQL을 가르친다 (Sams Teach Yourself ...).”.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.