[DB] SQL ) GROUP BY, HAVING ...etc

김태준·2023년 11월 15일

데이터베이스

목록 보기
4/4

그룹화란?

데이터를 특징별로 분류하여, 이를 기준으로 분석하는 기법이다. 단 몇 줄의 쿼리로, 수 많은 데이터를 분류 및 집계할 수 있다.

다만 GROUP BY에 명시된 컬럼만을 가지고 조회할 수 있다.
(그룹 화 이후에 일반 컬럼을 SELECT 할 수 없다.)

그룹 필터링이란?

GROUP화 된 컬럼을 필터링 하는 것

정렬이란?

ORDER BY를 통해 record를 정렬하는 것

LIMIT란?

조회 개수를 지정하는 것

DB 데이터

문제

GROUP BY

1. 결제(payments) 테이블을 결제 방법에 따라 분류하고, 각각의 결제 횟수를 조회하시오.

SELECT 
 ptype        AS "결제 방법",
 COUNT(ptype) AS "결제 횟수"
FROM
 payments
GROUP BY
 ptype

2. 상품(products) 테이블을 보관 타입에 따라 분류하고, 각각의 상품 개수와 평균 가격을 조회하시오.

SELECT 
  ptype        AS "상품보관 타입",
  COUNT(ptype) AS "상품 개수",
  AVG(price)   AS "평균 가격"
FROM
  products
GROUP BY
  ptype

3. 사용자(users)와 주문(orders) 테이블을 조인하고, 사용자 닉네임별 배송 완료 주문수를 조회 하시오.

SELECT 
   users.nickname AS "사용자 닉네임",
   COUNT(*)       AS "배송주문 완료 횟수"
FROM
   users
JOIN orders ON
   orders.user_id = users.id
  AND
   orders.status = 'DELIVERED'
GROUP BY
   users.nickname

문제

HAVING

1. 결제(payments) 테이블에서 수단별 평균 결제 금액이 다음과 같을 때, 평균 결제금액이 36,000원 이상인 것만 조회하시오.

SELECT 
  ptype                 AS "결제 방식",
  ROUND(AVG(amount),2)  AS "평균 결제 금액"
FROM 
  payments
GROUP BY
  ptype
HAVING  
AVG(amount) >= 36000
;

2. 다음 쿼리는 상품명과 가격을 기준으로, 누적 판매정보를 조회한다. 이를 참고하여 주어진 문제를 푸시오.

-- 상품 이름과 가격을 기준으로, 누적 판매정보(판매량, 매출)를 조회
SELECT -- 4
products.name AS "상품명",
products.price AS "가격",
SUM(order_details.count) AS "누적 판매량",
SUM(products.price * order_details.count) AS "누적 매출"
FROM -- 1
products
LEFT JOIN order_details ON -- 2
order_details.product_id = products.id
GROUP BY -- 3
products.name,
products.price
;

(a) 누적 매출이 35,000원 이상인 상품을 조회하시오.

-- 상품 이름과 가격을 기준으로, 누적 판매정보(판매량, 매출)를 조회
SELECT                                     -- 4
  products.name                             AS "상품명",
  products.price                            AS "가격",
  SUM(order_details.count)                  AS "누적 판매량",
  SUM(products.price * order_details.count) AS "누적 매출"
FROM                                       -- 1
  products
LEFT JOIN order_details ON                 -- 2
  order_details.product_id = products.id
GROUP BY                                   -- 3
  products.name,
  products.price
HAVING
  SUM(products.price * order_details.count) >= 35000
;

(b) 누적 매출이 2만원 이상이면서, 누적 판매량도 10개 이상인 상품을 조회하시오.

-- 상품 이름과 가격을 기준으로, 누적 판매정보(판매량, 매출)를 조회
SELECT                                     -- 4
  products.name                             AS "상품명",
  products.price                            AS "가격",
  SUM(order_details.count)                  AS "누적 판매량",
  SUM(products.price * order_details.count) AS "누적 매출"
FROM                                       -- 1
  products
LEFT JOIN order_details ON                 -- 2
  order_details.product_id = products.id
GROUP BY                                   -- 3
  products.name,
  products.price
HAVING
  SUM(products.price * order_details.count) >= 20000
    AND
  SUM(order_details.count) >= 10
;

(c) 누적 매출이 없는 제품을, 가격을 기준으로 오름차순 정렬하여 조회하시오.

-- 상품 이름과 가격을 기준으로, 누적 판매정보(판매량, 매출)를 조회
SELECT                                     -- 4
  products.name                             AS "상품명",
  products.price                            AS "가격",
  SUM(order_details.count)                  AS "누적 판매량",
  SUM(products.price * order_details.count) AS "누적 매출"
FROM                                       -- 1
  products
LEFT JOIN order_details ON                 -- 2
  order_details.product_id = products.id
GROUP BY                                   -- 3
  products.name,
  products.price
HAVING
 SUM(products.price * order_details.count) IS NULL
ORDER BY
 products.price
;

(d) 누적 매출 상위 5개 상품을 조회하시오.

-- 상품 이름과 가격을 기준으로, 누적 판매정보(판매량, 매출)를 조회
SELECT                                     -- 4
  products.name                             AS "상품명",
  products.price                            AS "가격",
  SUM(order_details.count)                  AS "누적 판매량",
  SUM(products.price * order_details.count) AS "누적 매출"
FROM                                       -- 1
  products
LEFT JOIN order_details ON                 -- 2
  order_details.product_id = products.id
GROUP BY                                   -- 3
  products.name,
  products.price
HAVING
 SUM(products.price * order_details.count) IS NOT NULL
ORDER BY
 "누적 매출" DESC 
LIMIT
 5
;

profile
Java_Spring_JPA_DB

0개의 댓글