[DB] JOIN, SUBQUERY

NORMAN·2023년 10월 26일
0

DB

목록 보기
6/6

JOIN

SQL 기본 문법 : JOIN(INNER, OUTER, CROSS, SELF JOIN)

원하는 결과를 얻기 위해 두 개의 테이블을 엮어야 하는 경우, 조인을 사용하여 두 개의 테이블을 엮어서 원하는 데이터를 얻을 수 있다.

두 테이블을 조인하기 위해선

  • 기본키와 외래키 관계로 맺어져야 한다. : 일 대 다 관계

INNER JOIN (내부 조인)

가장 많이 사용하는 조인 (그냥 조인이라 부르면 내부 조인 의미)

SELECT 열 목록
FROM 첫 번째 테이블
	INNER JOIN 두 번째 테이블
    ON 조인 조건
  [WHERE 검색 조건]

OUTER JOIN (외부 조인)

한 쪽에만 데이터가 있어도 결과가 나온다.

SELECT 열 목록
FROM 첫 번째 테이블(LEFT)
	<LEFT | RIGHT | FULL> OUTER JOIN 두 번째 테이블(RIGHT)
    ON 조인 조건
  [WHERE 검색 조건]

LEFT : 왼쪽 테이블의 모든 값이 출력되는 조인
RIGHT : 오른쪽 테이블의 모든 값이 출력되는 조인
FULL : 왼쪽 또는 오른쪽 테이블의 모든 값이 출력되는 조인

CROSS JOIN (상호 조인)

한 쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인
-> 상호 조인 결과의 전체 행 개수는 두 테이블의 각 행의 개수를 곱한 수
카티션 곱(cartesian product)라고도 한다.

SELECT *
FROM 첫 번쨰 테이블
	CROSS JOIN 두 번째 테이블

SELF JOIN (자체 조인)

자기 자신과 조인 -> 1개 테이블 사용
별도의 문법 X, 1개로 조인하면 자체 조인

SELECT 열 목록
FROM 테이블 별칭 A
	INNER JOIN 테이블 별칭 B
  [WHERE 검색 조건]

JOIN 5줄 요약

  • 조인은 두 개의 테이블을 서로 묶어서 하나의 결과를 만들어 내는 것
  • INNER JOIN : 두 테이블을 조인할 때, 두 테이블 모두 지정한 열의 데이터가 있어야 한다.
  • OUTER JOIN : 두 테이블을 조인할 때, 1개의 테이블에만 데이터가 있어도 결과가 나온다.
  • CROSS JOIN : 한 쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인하는 기능
  • SELF JOIN : 자기 자신과 조인, 1개의 테이블 사용

SUBQUERY (서브쿼리)

하나의 SQL 문 안에 포함되어 있는 또 다른 SQL 문, 메인쿼리가 서브쿼리를 포함하는 종속적인 관계

#메인쿼리
SELECT *
FROM 메인테이블
WHERE 서브테이블fk IN (
	#서브쿼리
    SELECT 서브테이블fk FROM 서브테이블 WHERE ..
    )

조인은 조인에 참여하는 모든 테이블이 대등한 관계 -> 모든 테이블의 칼럼을 어느 위치에서라도 사용 가능
서브쿼리는 메인쿼리의 컬럼 모두 사용 가능, 메인쿼리는 서브쿼리의 칼럼을 사용할 수 없음

조인은 집합간의 곱의 관계

  • 1 : 1 JOIN = 1레벨의 집합
  • 1 : N JOIN = N레벨의 집합
  • N : M JOIN = NM레벨의 집합

서브쿼리는 서브쿼리 레벨과 상관없이 항상 메인쿼리의 레벨로 결과 집합 생성

상황에 맞게 조인 / 서브쿼리 사용이 중요

서브쿼리 주의할 점

  • 서브쿼리를 괄호로 감싸서 사용
  • 서브쿼리는 단일 행 또는 복수 행 연산자와 함께 사용 가능
  • ORDER BY 사용 불가

서브쿼리 사용 가능한 곳

  • SELECT
  • FROM
  • WHERE
  • HAVING
  • ORDER BY
  • INSERT 문의 VALUES
  • UPDATE 문의 SET

종류

단일행 서브쿼리 (Single Row Subquery)

SELECT *
FROM Player
WHERE Team_ID = (
	SELECT Team_ID
    FROM Player
    WHERE Player_name = "norman"
    )
ORDER BY Team_name;

다중행 서브쿼리 (Multiple Row Subquery)

SELECT *
FROM Player
WHERE Team_ID IN (
	SELECT Team_ID
    FROM Player
    WHERE Player_name = "norman"
    )
ORDER BY Team_name;

다중컬럼 서브쿼리 (Multi Column Subquery)

SELECT *
FROM Player
WHERE (Team_ID, Height) IN (
	SELECT Team_ID
    FROM Player
    WHERE Player_name = "norman"
    )
ORDER BY Team_ID, Player_name;

위치에 따라 사용되는 서브쿼리

SELECT 절에서 사용

SELECT Player_name, Height, (
	SELECT AVG(Height)
    FROM Player p
    WHERE p.Team_ID = x.Team_ID) as AVG_Height
FROM Player x

FROM 절에서 사용

FROM 절에서 사용되는 서브쿼리를 인라인 뷰(Inline View)라고 한다.
FROM 절에는 테이블 명이 오도록 되어 있다.
-> 서브쿼리가 FROM절에 사용되면 뷰(View)처럼 결과가 동적으로 생성된 테이블로 사용할 수 있다
임시적이라 DBdp 저장되진 않는다.
또한, 인라인 뷰로 동적으로 생성된 테이블이라 인라인 뷰의 칼럼은 자유롭게 참조가 가능하다.

SELECT t.Team_name, p.Player_name, p.Height
FROM Player t, (
	SELECT Team_ID, Player_name, Back_no
    FROM Player
    WHERE Position = 'MF') p
WHERE p.Team_ID = t.Team_ID;

WHERE 절에서 사용

SELECT Player_name
FROM Player
WHERE Team_ID IN (
	SELECT Team_ID
    FROM Team
    WHERE Team_country = 'KOR'
    )

Reference

https://snowple.tistory.com/360

profile
백엔드 개발자 노먼입니다.

0개의 댓글