개발 학습 실습실

이 사이트의 실습은 자바스크립트를 켜야 움직입니다. 아래는 같은 내용을 글로 적은 것입니다.

공부 › DB › SQL

JOIN과 GROUP BY

조건을 ON에 쓰느냐 WHERE에 쓰느냐

회원 3명과 주문 4건을 조인합니다. 조인 종류, 조건을 쓰는 위치, 집계 방식에 따라 결과 행이 달라집니다. SQL은 FROM/JOIN → WHERE → GROUP BY → HAVING 순으로 처리되며, 단계마다 남는 행을 따라가 보면 이유가 보입니다.

실행으로 대조 · SQLite에서 18가지 조합의 SQL을 실행해 대조

이 실습에 나오는 개념

JOIN (INNER, OUTER)
두 테이블의 행을 조건에 따라 결합하는 연산이다. INNER JOIN은 양쪽에서 조건이 맞는 행만 결과에 포함한다. LEFT OUTER JOIN은 왼쪽 테이블의 모든 행을 포함하고 오른쪽에 짝이 없으면 NULL로 채운다. 짝이 없는 데이터도 결과에 남겨야 하는지에 따라 선택한다.
GROUP BY, WHERE, HAVING
GROUP BY는 지정한 컬럼의 값이 같은 행들을 묶어 그룹별 집계(합계, 개수 등)를 구한다. WHERE는 그룹으로 묶기 전에 개별 행을 걸러내고, HAVING은 묶은 뒤에 그룹을 걸러낸다. 따라서 집계 결과에 대한 조건은 HAVING에, 그 외의 조건은 WHERE에 쓴다.
기본 키, 유니크 키, 외래 키
기본 키(PK)는 테이블의 각 행을 유일하게 식별하는 컬럼으로 값이 중복되거나 비어 있을 수 없고 테이블에 하나만 둔다. 유니크 키는 값의 중복을 막는 제약으로 여러 개 둘 수 있다. 외래 키(FK)는 다른 테이블의 기본 키(또는 유니크 키)를 참조하는 컬럼으로, 참조 대상이 실제로 존재하도록 보장한다.

이렇게 바꿔 보세요

처음 설정으로 실행하면

  1. 1단계 FROM과 JOIN: 회원마다 ON 조건(회원 번호가 같음)에 맞는 주문을 찾아 붙입니다. 짝이 없는 회원도 버리지 않고, 주문 쪽 컬럼을 NULL로 채워 한 줄 남깁니다. 5행이 됐습니다.
  2. 2단계 WHERE: 조인이 끝난 결과에서 o.status = 'PAID'인 행만 남깁니다. 2행이 빠졌습니다. 박민수의 행은 o.status가 NULL이라 조건에 맞지 않아 함께 사라졌습니다. LEFT JOIN으로 남겨 둔 의미가 없어져 INNER JOIN과 같은 결과가 됩니다.
  3. 최종 결과: 3행.

실행 결과

코드

SELECT m.name, o.id, o.status
  FROM member m
  LEFT JOIN orders o
    ON o.member_id = m.id
 WHERE o.status = 'PAID';

이 모형의 전제

회원 3명, 주문 4건의 작은 예입니다. 결과는 표준 SQL의 논리적 처리 순서에 따라 직접 계산한 것입니다. 실제 DB는 내부적으로 순서를 바꿔 실행하기도 하지만(예: WHERE 조건을 조인보다 먼저 적용) 결과는 이 순서로 처리한 것과 같아야 합니다. 18가지 조합 모두, 화면에 나오는 SQL을 실제 SQL 엔진(SQLite)에서 그대로 실행한 결과와 최종 행이 일치하는 것을 확인했습니다.

앞 실습: SELECT가 처리되는 순서 · 다음 실습: 서브쿼리

이 실습에 나오는 개념

이 실습에서 보는 것

설정

코드


      
    

그림

실행 비교

이렇게 바꿔 보세요