답변:
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 ...).”.