[SQL] 10장. 데이터 그룹핑

김상현·2022년 9월 27일
0

SQL

목록 보기
10/22
post-thumbnail

[손에 잡히는 10분 SQL - 벤 포터 지음, 박남혜 옮김] 책의 학습 후 정리자료입니다.


📍 그룹 생성하기

  • 그룹은 SELECT 문에서 GROUP BY 절을 사용하여 생성할 수 있다.
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id;

  • GROUP BY 절은 DBMS에게 vend_id 으로 그룹핑하고 데이터를 정렬하라고 명령한다.
  • 이 절은 전체 테이블에 있는 데이터가 아니라 같은 vend_id 의 값이 나올 때마다 num_prods 의 값을 증가시킨다.
  • GROUP BY 절을 사용하면 자동으로 각 그룹에 대해 계산하기 때문에, 계산할 그룹을 따로 명시할 필요가 없다.
  • GROUP BY 절은 DBMS에게 먼저 데이터를 그룹핑한 후, 각각의 그룹에 대해 계산하라고 지시한다.

💡 GROUP BY 절의 규칙

  • GROUP BY 절에는 원하는 만큼의 열을 써서, 중첩(nested) 그룹을 만들 수 있다. 이 방식은 데이터를 그룹핑하는 방식을 좀 더 세밀하게 제어할 수 있다.
  • GROUP BY 절에 중첩된 그룹이 있다면, 데이터는 마지막으로 지정된 그룹에서 요약된다. 즉, 지적된 열은 그룹핑할 때 같이 측정된다(따라서 각 열 단위로는 데이터를 얻지 못한다).
  • GROUP BY 절에 있는 열을 가져오는 열이거나, 그룹 함수는 아니면서 유효한 수식이어야 한다. SELECT 절에서 수식을 사용한다면, GROUP BY 절에도 같은 수식을 사용해야 한다. 별칭은 사용할 수 없다.
  • 대부분의 SQL 실행 환경에서는 GROUP BY 절에서 문자나 메모와 같은 가변형 길이의 데이터형은 사용할 수 없다.
  • 그룹 함수 명령문을 제외하고 SELECT 절에 있는 모든 열은 GROUP BY 절에 존재해야 한다.
  • 그룹핑하는 열의 행에 NULL 값이 있다면, NULL도 그룹으로 가져온다, 여러 행이 NULL 값을 가진다면 모두 함께 그룹핑된다.
  • GROUP BY 절은 WHERE 절 뒤에 그리고 ORDER BY 절 앞에 와야 한다.

📍 그룹 필터링하기

  • GROUP BY 절을 사용하여 데이터를 그룹핑하는 것뿐만 아니라, SQL은 어떤 그룹을 포함하고 어떤 그룹은 배제할 것인지 필터링도 가능하게 해준다.
  • 필터링을 위해 WHERE 절을 사용해야할 것 같지만 WHERE 절은 행을 필터링하기 대문에 그룹에서는 적용할 수가 없다.
  • SQL 문은 위 문제를 해결하기 위해서 HAVING이라는 절을 제공한다.
  • WHERE 절은 행을 필터링하고, HAVING 절은 그룹을 필터링한다는 차이점이 있다.
SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;

  • WHERE 절과 HAVING 절을 모두 사용한 경우
    • 물건의 가격(prod_price)이 4 이상이고, 제품을 2개 이상 가진 판매처를 출력한 경우
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
WHERE prod_price >= 4
GROUP BY vend_id
HAVING COUNT(*) >= 2;

📍 그룹핑과 정렬

  • GROUP BY 절과 ORDER BY 절은 매우 다르다는 것을 이해하는 것이 중요하다.

📒 GROUP BY

  • 결과를 정렬한다.
  • 어떤 열이라도 (가져오지 않은 열도) 사용할 수 있다.
  • 필수 항목은 아니다.

📒 ORDER BY

  • 행을 그룹핑한다. 결과는 그룹 순서대로 출력되지 않을 수 있다.
  • 선택된 열이나 수식만 사용할 수 있고 선택된 열이나 수식을 꼭 사용해야 하낟.
  • 그룹 함수와 함께 사용하는 열(또는 수식)이 있는 경우 필수 항목이다.

💡 ORDER BY를 잊지 말자!

  • GROUP BY 절을 사용할 때마다 ORDER BY 절을 명시해야 한다. 그렇게 해야 데이터가 제대로 정렬되었다고 확신할 수 있다.
  • GROUP BY 절이 데이터를 정확히 정렬해 줄 것이라고 기대하지 말자.
SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY order_num
HAVING COUNT(*) >= 3
ORDER BY items, order_num;

📍 SELECT 문 순서

설명필수
SELECT가져올 열이나 수식YES
FROM데이터를 가져올 테이블테이블에서 데이터를 가져올 때 사용한다.
WHERE행 레벨 필터링NO
GROUP BY그룹 지정그룹핑한 데이터로 집계 계산을 할 때 사용한다.
HAVING그룹 레벨 필터링NO
ORDER BY정렬 순서NO

📍 도전 과제

  1. OrderItems 테이블은 각각의 주문에 대한 개별 항목을 포함하고 있다, 주문 번호(order_num)에 해당하는 줄 수를 order_lines 라고 표시하고, 결과를 order_lines로 정렬하는 SQL 문을 작성하라.
SELECT order_num, COUNT(*) AS order_lines
FROM OrderItems
GROUP BY order_num
ORDER BY order_lines;

  1. Products 테이블에 있는 prod_price를 사용하여, 각 판매처에서 취급하는 가장 저렴한 항목을 cheapest_item 이라고 이름 짓고 가격순(최저가에서 최고가)으로 정렬하는 SQL 문을 작성하라.
SELECT vend_id, MIN(prod_price) AS cheapest_item
FROM Products
GROUP BY vend_id
ORDER BY cheapest_item;

  1. 최고의 고객을 식별하는 게 중요하므로 100개 이상의 항목을 주문한 주문 번호(OrderItems 테이블의 order_num 이용)를 가져오는 SQL 문을 작성하라.
SELECT order_num
FROM OrderItems
GROUP BY order_num
HAVING SUM(quantity) >= 100
ORDER BY order_num;

  1. 얼마만큼 비용을 지출했는지가 최고의 고객을 판단하는 또 다른 방법이다. 주문액의 합이 1000 이상인 모든 주문의 주문 번호(OrderItmes 테이블의 order_num)를 가져와 주문 번호로 정렬하는 SQL 문을 작성하라. 이를 해결하려면 item_price 와 수량을 곱한 값을 모두 합해야 한다.
SELECT order_num, SUM(item_price*quantity) AS total_price
FROM OrderItems
GROUP BY order_num
HAVING SUM(item_price*quantity) >= 1000
ORDER BY order_num;

  1. 다음 SQL 문은 무엇이 잘못되었는가?
SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY itmes
HAVING COUNT(*) >= 3
ORDER BY items, order_num;
  • GROUP BY 절의 대상인 items 는 별칭이므로 그룹핑의 대상이 될 수 없다.
  • itemsorder_num 으로 변경한다.
SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY order_num
HAVING COUNT(*) >= 3
ORDER BY items, order_num;

profile
목적 있는 글쓰기

0개의 댓글