Do It SQL입문 03-5 데이터 그룹화 다루기

stan·2023년 6월 21일
0

T - SQL (SQL Server)

목록 보기
9/12
  • 데이터를 검색할 때 공통 그룹 의 정보를 확인해야 할 때가 있다

  • 데이터를 그룹화 할때는 GROUP BY 문을 사용

  • 데이터를 필터링 할 때는 HAVING 문을 사용

GROUP BY 문과 HAVING 문의 기본 형식

SELECT [열] FROM [테이블] WHERE [열] = [조건문] GROUP BY [열] HAVING [열] = [조건문]

1) GROUP BY : 데이터를 그룹화하는 구문
2) [열] : 기룹화 기준의 열 이름을 지정. 1개이상 그룹화 할 수 있음
3) [HAVING] : WHERE와 비슷한 기능을 하며 그룹화된 결과의 필터링 기능을 함
4) [조건값] : HAVING 필터에 적용할 조건값을 입력한다.

GROUP BY 문으로 데이터 그룹화하기

  • GROUP BY 문은 지정한 열에 있는 데이터를 그룹화한다.
  • nasdaq_company 테이블에 저장된 데이터에서 sector 열의 데이터 종류는 무엇이고
    몇 건의 데이터가 있는지 궁금 하다면?

1개 열 기준으로 그룹화하기

  • 반드시 그룹화할 기준 열을 지정 해야 함

sector로 그룹화

SELECT sector FROM nasdaq_company
GROUP BY sector

industry로 그룹화

SELECT industry FROM nasdaq_company
GROUP BY industry

  • 이러한 그룹화는 중복된 결과를 제외해 보여 줌

====================================================================


2개 이상의 열 기준으로 그룹화 하기

  • 열을 2개이상 지정해 그룹화하는 경우에는 GROUP BY에 나열한 열 순서대로 데이터를 그룹화할 뿐이고 전체 결과는 달라지지 않는다

GROUP BY 절에 컬럼 2개 쓰면 둘 다 달라야 다른 값 취급 !!

  • 직급, 부서로 그룹바이를 하면

영업 부장
영업 대리
개발 부장
개발 사원
회계 사원

  • 직급이랑 부서가 모두 같아야 같은 취급

중복 되어도 다른 값은 각각 다 나오고
두개가 같은게 여러개 있으면 그 여러개만 한개로 나오고

  • 연봉을 알고싶어

그럼 데이터베이스 입장에선 무슨 영업부장의 연봉? 여러명이잖아
SUM, COUNT, AVG 등등을 쓰는거야

이렇게 하면 오류 :

SELECT 직급, 부서, 연봉 FROM 테이블
GROUP BY 직급, 부서

  • 근데 중복제거하는 DISTINCT는 오류 안남. ㄹㅇ 중복을 제거만 해서
    그래서 연봉 알려줘~ 이러면 그냥 영업부장 연봉중에 제일 먼저꺼 알려줌

e.g. sector, industry 열 순서로 그룹화하면 sector 열로 우선 그룹화한 다음 industry 열로 그룹화한 결과를 출력

SELECT sector, industry FROM nasdaq_company
GROUP BY sector, industry

반대로 industry, sector 열 순서로 그룹화 하면 industry 열로 우선 그룹화한 다음 sector 열 순서로 그룹화한 결과를 출력한다.

SELECT sector, industry FROM nasdaq_company
GROUP BY industry, sector

둘다 236 행


====================================================================


집계함수 COUNT로 그룹화한 열의 데이터 개수 확인하기

각 그룹에 몇 개의 행이 있는지 세어 보는 쿼리

sector 열을 기준으로 그룹화한 다음 COUNT 함수로 그룹화한 각 행이 몇 개인지 검색하는 쿼리이다. 이때 COUNT 함수에는 AS cnt를 붙였는데 이는 개수를 센 결과는 출력할 때 열 이름을 cnt로 한다는 뜻

SELECT sector, COUNT(*) AS cnt FROM nasdaq_company
GROUP BY sector

14개 행


sector, industry 열을 기준으로 그룹화한 다음 각 그룹에 해당하는 데이터가 몇 개인지 센 것이다. ORDER BY 문을 입력한 이유는 검색한 데이터의 결과를 정렬해 행 개수를 쉽게 확인하려는 것이다. 그룹화한 열 순서에 따라 오름차순으로 정렬

SELECT sector, industry, COUNT(*) AS cnt FROM nasdaq_company
GROUP BY sector, industry
ORDER BY sector, industry


GROUP BY 문에 사용한 열 이름이 SELECT 문에 그대로 사용되었음을 파악

  • 데이터를 그룹화할 때는 그룹 기준이 되는 열이 필요하므로 GROUP BY 문에 사용한 열을 반드시 SELECT 문에도 사용해야 한다.
  • 만약 GROUP BY 문에 사용한 열을 SELECT 문에 사용하지 않으면 오류가 발생할 것이다.

====================================================================


HAVING 문으로 그룹화한 데이터 필터링하기

  • 그룹화한 데이터에서 데이터를 필터링하려면 HAVING 문을 사용해야 한다. HAVING 문은 WHERE 문과 비슷하지만 WHERE 문은 테이블에 있는 열에 적용하는 것이라면 HAVING문은 SELECT 문이나 GROUP BY 문에 사용한 열에만 적용 할 수 있다.

sector, industry 열을 기준으로 그룹화한 데이터에서 industry가 'Advertising'인 데이터만 검색한다.

SELECT sector, industry FROM nasdaq_company
GROUP BY sector, industry
HAVING industry = 'Advertising'


sector 열을 기준으로 그룹화한 다음 그룹화한 데이터의 개수가 1,000보다 큰 것만 검색하는 쿼리이다.

SELECT sector, COUNT(*) AS cnt FROM nasdaq_company
GROUP BY sector
HAVING COUNT(*) > 1000


그룹화에 사용하지 않은 열을 HAVING 문에 사용하면 오류가 발생

SELECT sector, COUNT(*) AS cnt FROM nasdaq_company
GROUP BY sector
HAVING industry = 'Advertising'

이 오류를 피하려면 HAVING문에 사용한 열을 SELECT문, GROUP BY 문에 추가한다

SELECT sector, industry, COUNT(*) AS cnt FROM nasdaq_company
GROUP BY sector, industry
HAVING industry = 'Advertising'
and COUNT(*) > 10


DISTINCT문으로 중복 데이터 제거하기

  • GROUP BY 문을 사용하지 않고도 중복 데이터를 제거하고 싶다면 DISTINCT문을 사용

DISTINCT문의 기본 형식 :

SELECT DISTINCT [열 이름] FROM [테이블 이름]

DISTINCT문은 지정한 열의 중복 데이터를 제거한다

DISTINCT문으로 nasdaq_company 테이블에서 sector, industry 열의 중복을 제거하는 쿼리

SELECT DISTINCT sector, industry
FROM nasdaq_company

GROUP BY 문으로 얻은 결과와 같다

결과가 같다고 해서 GROUP BY 문과 DISTINCT 문이 같지는 않다.
DISTINCT문은 중복을 제거할 뿐이지 집계하거나 계산을 할 수는 없다
집계나 계산이 필요하다면 GROUP BY문을 사용

퀴즈 8 : nasdaq_company 테이블에서 ipo_year 그룹별로 등록된 symbol개수를 출력하세요

SELECT
ipo_year, COUNT(*) AS cnt
FROM nasdaq_company
GROUP BY ipo_year, sector
HAVING COUNT(*) >= 20
ORDER BY cnt DESC

퀴즈 9 : nasdaq_company 테이블에서 IPO 연도별로 등록된 symbol 개수가 20개이상인 sector 목록을 내림차순(symbol 개수가 많은순서)으로 출력하세요

SELECT ipo_year, sector, COUNT(*) AS cnt
FROM nasdaq_company
GROUP BY ipo_year, sector
HAVING COUNT(symbol) symbol > 20
ORDER BY cnt DESC

symbol이 ipo_year와 연관이 있음

HAVING COUNT(symbol) symbol > 20

HAVING COUNT(*) > 20

  • 둘이 같은거
  • 실무에서 누군가에게 팔아야 하는 입장이면 와일드카드 안씀
    - 내수용은 씀

퀴즈 9 : nasdaq_company 테이블에서 IPO 연도별로 등록된 symbol 개수가 20개이상인 sector 목록을 내림차순(symbol 개수가 많은순서)으로 출력하세요

SQL

출력 테이블설정 조건절

출력

~별
~(으)로

테이블설정

조건절
~인
~한
~을 가진

profile
이진 입니다

0개의 댓글