티스토리 뷰
안녕하세요, 끙정입니다.
오늘은 다른 형식의 집계 함수인 GROUP BY에 대해 알아보겠습니다.
1.GROUP BY
우리가 만일 각 부서별 평균 월급을 알고 싶다면, 부서마다 AVG 함수를 호출하면 됩니다.
다음과 같이 말이죠.
그러나 굉장히 비효율적이라는 것을 아실겁니다.
부서가 수십개라면, 수십개의 쿼리를 따로 날려줘야하고,
한 눈에 보기도 힘듭니다.
이럴때 사용하는 것이 바로 GROUP BY입니다.
GROUP BY는 기준 필드가 같은 레코드를 모아 통계값을 구합니다.
또한 기준 필드는 집계 함수와 함께 쓸 수 있어 목록도 보기 좋게 출력할 수 있습니다.
/* GROUP BY 와 필드를 넣어준다. */
SELECT depart, AVG(salary) FROM tStaff GROUP BY depart;
GROUP BY는 단지 그룹핑을 해주는 것 뿐이며, 어떤 통계를 낼 것인가는 필드 목록의 집계 함수에 따라 달라집니다.
여러 개의 집계 함수를 동시에 사용할 수도 있습니다.
/* depart 별로 GROUP BY를 한다. */
/* depart 이름을 출력해주고 */
/* 부서별 레코드의 COUNT를 출력해주고 */
/* 부서별 joindate의 최댓값을 출력해주고 */
/* 부서별 score의 평균값을 출력한다. */
SELECT depart, COUNT(*), MAX(joindate), AVG(score) FROM tStaff GROUP BY depart;
1-1. GROUP BY의 기준 필드
GROUP BY의 목적은 그룹핑을 통한 그룹 통계를 내는 것이기 때문에 기준 필드를 어떤 것으로 할 것인지가 중요합니다.
고유값만이 존재하는 필드는 그룹핑이 되지 않기 때문에 의미가 없다는 것이지요.
이름별 Salary의 합?! 그룹핑의 의미가 없다.
기준 필드를 여러개 쓰는 것도 가능합니다.
기준 필드를 두 개를 쓴다면, 첫 번째 기준으로 나누고, 다시 두 번째 기준으로 또 나눕니다.
/* depart X gender 를 기준으로 그룹핑 한다. */
SELECT depart, gender, COUNT(*) FROM tStaff GROUP BY depart, gender;
각 부서별, 성별 기준으로 count
부서를 먼저 나누고 성별을 구분하는 것이나, 성별을 나눈 후 부서를 구분하는 것이나 결과는 같습니다.
출력 순서가 다른 것 뿐인데,
어차피 필드 순서는 필드 목록에서 지정이 가능하고,
레코드 순서는 ORDER BY로 조정이 가능하기 때문입니다.
2. HAVING
HAVING절은 GROUP BY의 다음에 오며, 통계 결과 중 출력할 그룹의 조건을 지정합니다.
WHERE절과 헷갈릴 수 있지만, 오직 GROUP BY의 조건절로만 쓰입니다.
/* 평균 임금이 340 이상인 부서만 출력하고 싶다. */
SELECT depart, AVG(salary) FROM tStaff GROUP BY depart HAVING AVG(salary) >= 340;
HAVING은 무조건 GROUP BY의 뒤에 오며, 정렬을 해주는 ORDER BY 보다 뒤로 갈 수는 없습니다.
언제나 출력을 마친 후에 정렬이 일어나기 때문입니다.
WHERE와 HAVING의 차이를 명확히 하기 위해 비교를 해보겠습니다.
/* HAVING 으로 조건을 준 쿼리 */
SELECT depart, AVG(salary) FROM tStaff GROUP BY depart HAVING AVG(salary) >= 340;
/* WHERE 로 조건을 준 쿼리 */
SELECT depart, AVG(salary) FROM tStaff WHERE salary >= 340 GROUP BY depart;
WHERE는 레코드에 조건을 거는 것이고,
HAVING은 그룹핑 된 결과에 조건을 거는 것입니다.
그렇기에 평균이 아예 다르게 집계 됩니다.
따라서 SELECT 문은 다음과 같은 순서를 가집니다.
SELECT 필드명 /* 이 필드를 출력해줘 */
FROM 테이블명 /* 이 테이블에 있는 */
WHERE 조건 /* 이 조건에 부합하는 레코드만 추려서 */
GROUP BY 필드기준 /* 그걸 이 필드기준으로 그룹핑 해줘 */
HAVING 조건 /* 그중에서 이 조건에 부합하는 그룹만 출력해줘 */
ORDER BY 필드기준 /* 마지막으로 그 결과를 이 필드를 기준으로 정렬 해줘 */
때때로 HAVING과 WHERE가 같은 결과를 출력해낼 때도 있지만,
내부적인 연산과정은 확연히 다릅니다.
쿼리는 효율성이 가장 중요하기 때문에 대체로 WHERE를 통해서 같은 결과를 출력하는 것이 빠를 것입니다.
다음과 같이 말이죠!
/* WHERE로 동일한 출력을 내보자 */
SELECT depart, MAX(salary) FROM tStaff
WHERE depart IN ('인사과', '영업부')
GROUP BY depart;
/* HAVING 으로 동일한 출력을 내보자 */
SELECT depart, MAX(salary) FROM tStaff
GROUP BY depart
HAVING depart IN ('인사과', '영업부');
두 쿼리는 동일한 결과를 냅니다-!
인사과, 영업부 중에서 그룹별로 가장 높은 임금을 출력해 달라는 쿼리입니다.
그러나 WHERE절을 쓴 쿼리는 모든 레코드에서 일단 인사과와 영업부 레코드만 추려서 그룹핑을 합니다.
반대로 HAVING절은 모든 레코드를 그룹핑해서 그 안에서 인사과와 영업부만 출력합니다.
출력 속도에 차이가 있는 것이 보이실 겁니다. (전자는 0.000 sec, 후자는 0.001 sec)
레코드가 몇개 없으면 별 차이 없지만,
레코드가 많다면 연산량이 급격히 늘어날 것입니다.
오늘은 그만 알아보겠습니다.
출처
http://www.yes24.com/Product/Goods/101637633
'SQL' 카테고리의 다른 글
삭제와 갱신에 대해서 알아보자 (feat. DELETE, TRUNCATE, UPDATE) (0) | 2023.01.29 |
---|---|
삽입문에 대해서 알아보자 (feat. INSERT, INSERT SELECT, CREATE SELECT) (2) | 2023.01.29 |
집계함수를 알아보자 (feat.COUNT, SUM, AVG ...) (0) | 2023.01.26 |
효율적으로 출력하는 법을 알아보자 (feat. DISTINCT, ROWNUM, TOP, LIMIT, OFFSET FETCH) (2) | 2023.01.26 |
ORDER BY 에 대해서 알아보자 (0) | 2023.01.26 |
- Total
- Today
- Yesterday
- Meta
- alexa
- ai pc
- Amazon
- perplexity
- searchgpt
- Apple
- OpenAI
- SSI
- 액침냉각
- ChatGPT
- IDC
- genai
- aichip
- Nvidia
- sb1047
- Intel
- sql
- apple intelligence
- Samsung
- datacenter
- aitv
- condenast
- galaxyai
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |