SQL

[SQL/MySQL] JOIN, UNION, WITH

mopipi 2024. 1. 22. 00:35
반응형

편의상, COL 데이터가 추가되며 확장되는 것을 열 방향 확장 (가로 방향 확장)
COL 데이터 추가 없이 데이터의 수가 늘어나는 것을 행 방향 확장 (COLUMN은 유지, 세로 방향 확장)이라 함

JOIN

✅ INNER JOIN (= JOIN)

두 개의 테이블에서 ON 조건을 만족하는 튜플만 뽑아서 출력 (열 방향 확장)

  • 두 테이블 모두 전체 데이터 보장이 어렵다
SELECT *
FROM A_TABLE
LEFT/RIGHT JOIN B_TABLE
ON A.KEY = B.KEY;

✅ LEFT JOIN

두 개의 테이블 중 왼쪽 테이블( A )을 기준으로 ON 조건을 만족하는 오른쪽 테이블( B )을 붙여 출력 (열 방향 확장)

  • 왼쪽 테이블( A )은 전체 데이터가 보존된 채, 걸러진 오른쪽 테이블의 COL이 추가됨
  • 만약 왼쪽 테이블의 COL 에 대해 데이터가 없는 경우 NULL로 표시됨

✅ RIGHT JOIN

두 개의 테이블 중 오른쪽 테이블( **B )을 기준으로 ON 조건을 만족하는 왼쪽 테이블( A )을 붙여 출력 **(열 방향 확장)

  • 오른쪽 테이블( B )은 전체 데이터가 보존된 채, 걸러진 왼쪽 테이블의 COL이 추가됨
  • 만약 오른쪽 테이블의 COL 에 대해 데이터가 없는 경우 NULL로 표시됨

✅ SELF JOIN

JOIN 없이 INNER JOIN 한 결과물 도출

  • FROM에 병합할 테이블 2개, WHERE에 ON 조건 명시

✅ FULL OUTER JOIN : 외부 조인

INNER JOIN과 반대. 공통 요소 + 알파를 모두 출력하고 싶은 경우 사용 (그냥 두 테이블을 합치고 싶을 때 사용하는 듯)

  • MYSQL은 FULL OUTER JOIN을 사용할 수 없다(???)
  • 따라서 {LEFT JOIN 결과물} UNION {RIGHT JOIN 결과물} 로 처리해 줘야 함

🔸 USING

만약, ON에 사용되는 컬럼명이 동일하다면, USING(컬럼명) 을 사용해 간단하게 나타낼 수 있다.

SELECT *
FROM TB1 JOIN TB2 
USING (ID) (≒ ON TB1.ID = TB2.ID)

UNION

✅ UNION

중복 상관 없이 두 출력값을 ROW 방향으로 이어 붙여 출력해줌 (행 방향 확장)

단, 병합하는 두 테이블의 COLUMN 개수가 일치해야 함!!

  • 만약 합치고 싶은 두 테이블의 COLUMN이 일치하지 않는다면, 존재하지 않는 열의 값을 NULL로 대체해 SELECT에서 출력 가능함.

✅ UNION ALL

중복된 튜플을 제거하여 ROW 방향으로 이어 붙여 출력해줌 (행 방향 확장)


✅ WITH

WITH TOTAL AS 
    (SELECT SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT
      FROM ONLINE_SALE
      UNION ALL
      SELECT SALES_DATE, PRODUCT_ID, NULL, SALES_AMOUNT
      FROM OFFLINE_SALE)
SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT
FROM TOTAL
WHERE SALES_DATE BETWEEN '2022-03-01 00:00:00' AND '2022-03-31 23:59:59'
ORDER BY SALES_DATE, PRODUCT_ID, USER_ID;

중복되는 SQL문의 반복 작성을 막기 위해 일종의 매크로 생성

  • 여러번 사용할 데이터를 뽑아내는 매크로를 WITH로 이름 지정한 뒤, 해당 결과물 테이블을 FROM 뒤에 쓰는 방식으로 2차 가공할 수 있다.

✅ WITH RECURSIVE 

가상 테이블 생성 뒤, 자신(가상 테이블)의 값을 계속 참조해 나가며 테이블 생성

   IF) 1 ~ 23의 값을 갖는 테이블 생성

WITH RECURSIVE H AS (
	SELECT 0 AS LEVEL -- 초기값 설정
   	UNION ALL
    	SELECT NUM + 1 FROM H
   	WHERE NUM < 23) -- 반복 조건

 


ROW_NUMBER & PARTITION

테이블 분할하는용도 (파티셔닝). 데이터 처리 성능 개선 + 파티션 내 순위 부여

SELECT ROW_NUMBER() OVER (PARTITION BY {묶을 기준 열} ORDER BY {...}) AS COL1,
       U_ID, ...
FROM TABLE;

 

 

 

참고

- https://velog.io/@nembizzang/SQL-%EA%B8%B0%EC%B4%88-6.-%EB%B3%91%ED%95%A9-%EA%B2%B0%ED%95%A9-UNION-JOIN-CONCAT

반응형