1. 데이터 조회(SELECT)
1-1. FROM
: SELECT * / FROM 테이블명;
SELECT * FROM CUSTOMER;
👉 : CUSTOMER 테이블의 모든 열을 조회하겠다.
1-2. WHERE
WHERE 조건;
: WHERE절은 FROM 절 다음에 작성되어야 한다.
1-3. GROUP BY
GROUP BY 그룹화할 열;
: GROUP BY 절은 FROM, WHERE 절 다음에 작성되어야 한다.
※ 이때 GROUP BY로 그룹화할 열은 SELECT로 조회해야한다.
(그룹화하는 이유가 열을 그룹화하여 조회하기 위함이므로)
EX) 거주지역별 남성회원수 출력
SELECT ADDR
,COUNT(MEM_NO) AS 회원수
FROM CUSTOMER
WHERE GENDER = "MAN"
GROUP
BY ADDR;
※ COUNT(MEM_NO)는 기존 열이 아니라 새롭게 함수로 만들어진 열이므로 ADDR로 그룹화되지 않고 열이 조회된다!
※ GROUP BY는 집계함수와 주로 사용되고, 여러 열별로 그룹화가 가능하다.
EX) 거주지역을 서울, 인천으로 필터링 + 거주지역 및 성별로 회원수 집계
1. 거주지역 서울, 인천 필터링 : WHERE절에서 IN 사용
SELECT ADDR
,GENDER
,COUNT(MEM_NO) AS 회원수
FROM CUSTOMER
WHERE ADDR IN ("SEOUL", "INCHEON")
GROUP
BY ADDR
,GENDER;
1-4. HAVING
HAVING 조건;
: GROUP BY와 함께 사용되며, GROUP BY 다음에 작성되어야 한다.
1-5. ORDER
**ORDER BY 정렬할 열 이름 / 정렬 방법;
: SELECT절 맨 끝에 작성되어야 한다.
2. 데이터 조회 실습
① CUSTOMER 테이블의 가입연도별 및 지역별 회원수 조회
SELECT ADDR
,YEAR(JOIN_DATE) AS 가입연도
,COUNT(MEM_NO) AS 회원수
FROM CUSTOMER
GROUP
BY ADDR
,YEAR(JOIN_DATE);
② ①에서 작성된 명령어에서 성별이 남성인 회원 조건 추가한 뒤,
회원수가 50명 이상인 조건 추가하시오.
SELECT ADDR
,YEAR(JOIN_DATE) AS 가입연도
,COUNT(MEM_NO) AS 회원수
FROM CUSTOMER
WHERE GENDER = "MAN"
GROUP
BY ADDR
,YEAR(JOIN_DATE)
HAVING COUNT(MEM_NO) >= 50;
③ ②에서 작성된 명령어에서 회원수를 내림차순으로 정렬하시오.
SELECT ADDR
,YEAR(JOIN_DATE) AS 가입연도
,COUNT(MEM_NO) AS 회원수
FROM CUSTOMER
WHERE GENDER = "MAN"
GROUP
BY ADDR
,YEAR(JOIN_DATE)
HAVING COUNT(MEM_NO) >= 50
ORDER
BY COUNT(MEM_NO) DESC;
3. 테이블 결합(JOIN) - 관계
ERM(Entity-Relationship Modeling)
ERD(Entity-Relationship Diagram)
FK : 다른 테이블에서 PK인 개체 (주문 테이블의 회원번호는 회원번호의 PK)
2-1. INNER JOIN : 두 테이블의 공통 값이 매칭되는 데이터만 결합
EX) CUSTOMER, SALES 테이블 INNER JOIN
SELECT *
FROM CUSTOMER AS A
INNER
JOIN SALES AS B
ON A.MEM_NO = B.MEM_NO;
👉 : CUSTOMER, SALES 테이블의 공통되는 열은 MEM_NO열이므로
ON A.MEM_NO = B.MEM_NO으로 공통된 회원번호를 기준으로 결합한다.
2-2. LEFT JOIN : 두 테이블의 공통 값이 매칭되는 데이터만 결합(INNER JOIN) + 왼쪽 테이블에 없는 오른쪽 테이블의 데이터는 NULL로 표시
EX) CUSTOMER, SALES 테이블 LEFT JOIN
SELECT *
FROM CUSTOMER AS A
LEFT
JOIN SALES AS B
ON A.MEM_NO = B.MEM_NO;
👉 : CUSTOMER, SALES 테이블에 공통으로 있는 회원번호를 기준으로 결합한다.
이때 B(오른쪽 테이블)에서 A와 공통되지 않은 회원번호는 NULL값으로 출력된다.
2-3. RIGHT JOIN : 두 테이블의 공통 값이 매칭되는 데이터만 결합(INNER JOIN) + 오른쪽 테이블에 없는 왼쪽 테이블의 데이터는 NULL로 표시
EX) CUSTOMER, SALES 테이블 RIGHT JOIN
SELECT *
FROM CUSTOMER AS A
RIGHT
JOIN SALES AS B
ON A.MEM_NO = B.MEM_NO;
👉 : CUSTOMER, SALES 테이블에 공통으로 있는 회원번호를 기준으로 결합한다.
이때 A(왼쪽 테이블)에서 B와 공통되지 않은 회원번호는 NULL값으로 출력된다.
※ INNER / LEFT / RIGHT JOIN 관계 다이어그램
2-4. 3개 이상 테이블 결합
EX) SALES 테이블 기준으로, CUSTOMER 테이블, PRODUCT 테이블 LEFT JOIN 결합
: 기준 테이블과 1개의 테이블을 결합 후 나머지 1개 테이블을 결합하면 된다.
SELECT *
FROM SALES AS A
LEFT
JOIN CUSTOMER AS B
ON A.MEM_NO = B.MEM_NO
LEFT
JOIN PRODUCT AS C
ON A.PRODUCT_CODE = C.PRODUCT_CODE;
4. 테이블 결합(JOIN) + 데이터 조회(SELECT) 실습
① SALES 테이블 기준으로 PRODUCT 테이블을 LEFT JOIN하시오.
SELECT *
FROM SALES AS A
LEFT
JOIN PRODUCT AS B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;
② ①에서 결합된 테이블을 활용하여, 브랜드별 판매수량을 구하시오.
SELECT BRAND
,SUM(SALES_QTY) AS 판매수량
FROM SALES AS A
LEFT
JOIN PRODUCT AS B
ON A.PRODUCT_CODE = B.PRODUCT_CODE
GROUP
BY BRAND;
③ CUSTOMER 및 SALES 테이블을 활용하여, 회원가입하고 주문이력이 없는 회원수를 구하시오.
SELECT COUNT(A.MEM_NO)
FROM CUSTOMER AS A
LEFT
JOIN SALES AS B
ON A.MEM_NO = B.MEM_NO
WHERE B.MEM_MO IS NULL;
5. 서브 쿼리(Sub Query)
4-1. SELECT절 서브 쿼리
: SELECT문 안에 또 다른 SELECT문이 있는 경우
: JOIN을 사용하지 않고 다른 테이블의 정보를 가져올 수 있다.
👉 : 테이블에 열을 추가하는 명령어이다.
SELECT *
,(SELECT GENDER FROM CUSTOMER WHERE A.MEM_NO=MEM_NO) AS GENDER
FROM SALES AS A;
👉 : SALES의 모든 열을 조회하고 SALES의 회원번호와 CUSTOMER의 회원번호가 같은 CUSTOMER 테이블의 행만 GENDER열을 추가한다.
하지만 SELECT절 서브 쿼리는 테이블 결합(JOIN)보다 처리 속도가 느리기때문에 잘 사용하지 않는다!
4-2. FROM절 서브 쿼리
: FROM절 안에 또 다른 SELECT문이 있는 경우
EX) 회원번호별 주문횟수 출력
SELECT *
FROM (
SELECT MEM_NO
,COUNT(ORDER_NO) AS 주문횟수
FROM SALES
GROUP
BY MEM_NO
) AS A;
👉 : FROM 다음에 테이블명이 와야하기때문에 괄호 안을 AS로 테이블명을 지정해줘야 한다(AS A).
4-3. WHERE절 서브 쿼리 = 리스트
: WHERE절 안에 SELECT문이 있는 경우
EX) 가입일자가 2019년인 회원의 주문횟수 조회
SELECT COUNT(ORDER_NO) AS 주문횟수
FROM SALES
WHERE MEM_NO IN (SELECT MEM_NO FROM SALES CUSTOMER YEAR(JOIN_DATE) = 2019);
WHERE절 서브 쿼리는 리스트의 형태이다!
6. 데이터 조회 + 데이터 결합 + 서브 쿼리 실습
① FROM절 서브 쿼리를 활용하여, SALES 테이블의 PRODUCT_CODE별 판매수량을 구하시오.
SELECT *
FROM (
SELECT PRODUCT_CODE
,SUM(SALES_QTY) AS 판매수량
FROM SALES
GROUP
BY PRODUCT_CODE
) AS A;
👉 : FROM절 서브 쿼리에서 PRODUCT_CODE별 판매수량을 구해놓고
밖의 SELECT에서 *으로 모두 출력하면 조건에 맞게 출력된다.
② ① 명령어를 활용하여, PRODUCT 테이블과 LEFT JOIN하시오.
SELECT *
FROM (
SELECT PRODUCT_CODE
,SUM(SALES_QTY) AS 판매수량
FROM SALES
GROUP
BY PRODUCT_CODE
) AS A
LEFT
JOIN PRODUCT AS B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;
👉 : FROM절 서브 쿼리가 FROM 다음 오는 테이블 역할을 하므로 JOIN에서 했던 것처럼 FROM 다음부터 JOIN 문법을 사용하여 결합하면 된다.
③ ② 명령어를 활용하여, 카테고리 및 브랜드별 판매수량을 구하시오.
SELECT CATEGORY
,BRAND
,SUM(판매수량) AS 판매수량
FROM (
SELECT PRODUCT_CODE
,SUM(SALES_QTY) AS 판매수량
FROM SALES
GROUP
BY PRODUCT_CODE
) AS A
LEFT
JOIN PRODUCT AS B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;
GROUP
BY CATEGORY
,BRAND;
출처 : 네이버 부스트코스 - '기초 데이터 분석을 위한 핵심 SQL'
SQL은 너무 생소하고 한번에 많은걸 배운 것 같아서
모를 때마다 이 글을 참고해야 할 것 같다!