본문 바로가기

Back-End 공부/Database

[Database] GROUP BY절, HAVING절

✅  GROUP BY

SELECT 컬럼명 FROM 테이블명 GROUP BY 컬럼명

 

- 집계함수

  • COUNT() : 행의 개수를 세어줌
  • AVG() : 행 안에 있는 값의 평균을 내어줌
  • MIN() : 행 안에 있는 값의 최솟값을 반환해줌
  • MAX() : 행 안에 있는 값의 최댓값을 반환해줌
  • SUM() : 행 안에 있는 값의 합을 내어줌
  • ROUND() : 몇 번째 소수점 자리에서 반올림

 

 

 

💻 GROUP BY 실습

 

post 테이블에 price 값 추가

 

1. post테이블 author_id로 그룹화한 데이터의 갯수구하는 집계 SQL

 
SELECT COUNT(author_id) FROM post;
 

 

 

2. 만약 post마다 원고료가 있었다면, select author_id, sum(price), avg(price) from post group by author_id

 
SELECT ROUND(AVG(price), 0) FROM post;
SELECT MIN(price) FROM post;
SELECT MAX(price) FROM post;
SELECT SUM(price) FROM post;
 

 

 

3. 작가 id별로 몇 개의 글을 썼는지 SELECT

 

 
SELECT author_id , COUNT(*) FROM post GROUP BY author_id;
 

 

 

 

4. 작가 id별로 price sum, price avg 구하기

 
SELECT author_id , ROUND(SUM(price), 0), ROUND(AVG(price),0) FROM post GROUP BY author_id;
 

 

 

✅  HAVING

  • HAVING 절은 GROUP BY를 사용하여 그룹화된 후의 데이터에 대한 조건을 설정
  • WHERE 절은 데이터를 그룹화하기 전의 개별 레코드에 대한 조건을 설정
  • HAVING 절은 주로 집계 함수(COUNT(), SUM(), AVG() 등)와 함께 특정 조건을 만족하는 그룹만을 필터링하고 싶을 때 사용
  • select author_id, count(*) as count from post group by author_id having count > 3;

 

💻 GROUP BY 실습

 

 

1. author_id별로 price 평균값을 구하시오.

단, 건별로 2000원 이상인 데이터만 평균을 내서 출력하시오.

 
SELECT author_id , AVG(price) FROM post WHERE price >= 2000 GROUP BY author_id;
 

=> 전체 데이터 중 2000원이 넘는 데이터를 찾는 것이기 때문에 WHERE 조건으로 찾아야 함

 

 

2. author_id 별로 price  평균값을 구하시오.

단, 그룹별 평균값이 2000원 이상인 데이터만 출력하시오.

 
SELECT author_id, AVG(price) FROM post GROUP BY author_id HAVING AVG(price)>=2000;
 

=> 그룹 안에 있는 데이터 중 2000원이 넘는 데이터를 찾는 것이기 때문에 HAVING 조건으로 찾아야 함

 

 

3. author_id별로 price 평균값을 구하시오.

단, 건별로 2000원 이상인 데이터 중 그룹별 평균값이 2000원 이상인 데이터만 출력하시오.

 
SELECT author_id, AVG(price) FROM post
WHERE price>=2000
GROUP BY author_id HAVING AVG(price) >= 2000
 

 

 

 

💻 프로그래머스 문제 풀기

 

(1) 입양 시각 구하기

https://rookie-programmer.tistory.com/141

 

[SQL] 입양 시각 구하기

⭐ 문제 보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 09:00부터 19:59까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는

rookie-programmer.tistory.com

 

(2) 성분으로 구분한 아이스크림 총 주문량

https://rookie-programmer.tistory.com/142

 

[SQL] 성분으로 구분한 아이스크림 총 주문량

⭐ 문제 상반기 동안 각 아이스크림 성분 타입과 성분 타입에 대한 아이스크림의 총주문량을 총주문량이 작은 순서대로 조회하는 SQL 문을 작성해주세요. 이때 총주문량을 나타내는 컬럼명은 TOT

rookie-programmer.tistory.com

 

(3) 자동차 종류 별 특정 옵션이 포함된 자동차 수 구하기

https://rookie-programmer.tistory.com/143

 

[SQL] 자동차 종류 별 특정 옵션이 포함된 자동차 수 구하기

⭐ 문제 CAR_RENTAL_COMPANY_CAR 테이블에서 '통풍시트', '열선시트', '가죽시트' 중 하나 이상의 옵션이 포함된 자동차가 자동차 종류 별로 몇 대인지 출력하는 SQL문을 작성해주세요. 이때 자동차 수에

rookie-programmer.tistory.com

 

(4) ⭐ 재구매가 일어난 상품과 회원 리스트 구하기

https://rookie-programmer.tistory.com/144

 

[SQL] 재구매가 일어난 상품과 회원 리스트 구하기

⭐ 문제 ONLINE_SALE 테이블에서 동일한 회원이 동일한 상품을 재구매한 데이터를 구하여, 재구매한 회원 ID와 재구매한 상품 ID를 출력하는 SQL문을 작성해주세요. 결과는 회원 ID를 기준으로 오름차

rookie-programmer.tistory.com

 

(+) 연습하기

 

SELECT REGION, ITEM, COUNT(*)

GROUP BY REGION, ITEM

HAVAING COUNT(*)>=2

 

출력결과

East   Apples      2

East   Grapes     1

East   Lemons    1

East   Oranges   2

 

 

 

(5) 입양 시각 구하기2

아래 WITH RECURSIVE 활용해볼 것

 

https://rookie-programmer.tistory.com/145

 

[SQL] 입양 시각 구하기2

⭐ 문제 보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는

rookie-programmer.tistory.com

 

 

 

- WITH RECURSIVE

WITH RECURSIVE 생성할 테이블명(컬럼명) AS (

   반복할 문장

)

 

  • SQL에서 재귀문으로서 자기 자신을 참조하여 반복적으로 데이터를 생성하거나 변형하면서 하나의 테이블을 만드는 용도로 사용
  • UNION과 함께 사용되며 데이터행을 더해나가는 방식
  • WHERE절은 재귀적으로 생성되는 각각의 행에 대해 평가되며, 조건이 거짓이 되는 순간 더 이상 새로운 행을 생성하지 않고 전체 재귀문이 STOP


ex)

WITH RECURSIVE number_sequence(HOUR) AS (     SELECT 0     UNION ALL     SELECT HOUR + 1 FROM number_sequence WHERE HOUR<23)

 

SELECT HOUR FROM number_sequence;

 

SELECT HOUR, 0 as COUNT FROM number_sequence;