답변:
MySQL에서 WHERE가 아닌 HAVING 후에 직접 생성 한 열 (예 : "1을 숫자로 선택")을 배치해야하는 이유는 무엇입니까?
WHERE이전 GROUP BY에 HAVING적용되고 이후에 적용되며 집계를 필터링 할 수 있습니다.
일반적으로,이 조항의도에 별칭을 참조 할 수 있지만, MySQL참조 허용 SELECT에 수준의 별칭을 GROUP BY, ORDER BY그리고 HAVING.
"WHERE 1"(열 이름 대신 전체 정의 작성) 대신에 단점이 있습니까?
계산 된 식에 집계가 포함되어 있지 않으면 WHERE절에 넣는 것이 더 효율적일 것입니다.
이 질문에 대한 다른 모든 대답은 핵심 요점에 부딪치지 않았습니다.
테이블이 있다고 가정하십시오.
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를 사용하는 것을 볼 수 있지만 행이 다릅니다.
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...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
HAVING에서 집계를 필터링하는 데 사용됩니다 GROUP BY.
예를 들어, 중복 이름을 확인하려면 다음을 수행하십시오.
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
이 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.*/
WHERE와 HAVING.
WHERE 는 데이터를 그룹화하기 전에 필터링하고 HAVING 은 데이터를 그룹화 한 후 필터링합니다. 이것은 중요한 차이점입니다. WHERE 절로 제거 된 행 은 그룹에 포함되지 않습니다. 이로 인해 계산 된 값이 변경되어 결과적으로 HAVING 절 에서 해당 값을 사용하여 필터링되는 그룹에 영향을 줄 수 있습니다.
그리고 계속
HAVING 은 WHERE 와 매우 유사하므로 GROUP BY 가 지정 되지 않은 경우 대부분의 DBMS가이를 동일한 것으로 취급 합니다. 그럼에도 불구하고, 당신은 그 구별을 스스로해야합니다. 사용 HAVING 단지와 함께 GROUP BY의 조항. 표준 행 수준 필터링 에는 WHERE 를 사용하십시오 .
발췌 : Forta, Ben. “샘은 10 분 (5 판)에 SQL을 가르친다 (Sams Teach Yourself ...).”.