SQL Reference
SQL 쿼리 레퍼런스
SQL Reference 소개
SQL 레퍼런스는 관계형 데이터베이스 개발을 위한 전체 SQL 문을 포괄하는 검색 가능한 빠른 참조입니다. SELECT 섹션에는 기본 쿼리, DISTINCT, AND/OR를 활용한 WHERE 필터링, ORDER BY 정렬, LIMIT/OFFSET 페이지네이션, LIKE 패턴 매칭, IN/BETWEEN 범위 조건, CASE WHEN 조건부 로직, COALESCE와 NULLIF를 활용한 NULL 처리가 포함됩니다. 각 항목은 바로 사용할 수 있는 쿼리 예제를 제공합니다.
이 레퍼런스는 SQL을 SELECT, JOIN, 집계함수, 서브쿼리, DDL, 인덱스의 6가지 카테고리로 구성합니다. JOIN 섹션에서는 일치하는 행을 위한 INNER JOIN, 일치하지 않는 행을 보존하는 LEFT/RIGHT JOIN, 완전 합집합을 위한 FULL OUTER JOIN, 카티션 곱을 위한 CROSS JOIN, 직원-매니저 관계 같은 계층형 데이터를 위한 SELF JOIN 등 모든 조인 유형을 다룹니다. 집계함수 섹션에서는 GROUP BY와 HAVING을 활용한 COUNT, SUM, AVG, MIN, MAX와 RANK, ROW_NUMBER OVER PARTITION BY를 사용한 윈도우 함수를 보여줍니다.
서브쿼리와 DDL 섹션은 중급에서 고급 SQL 패턴을 다룹니다. 서브쿼리에는 WHERE IN 서브쿼리, 상관 존재 확인을 위한 EXISTS, 인라인 뷰를 위한 파생 테이블, 가독성 높은 재귀 및 다단계 쿼리를 위한 CTE(WITH 절), 결과 집합 결합을 위한 UNION/UNION ALL이 포함됩니다. DDL과 인덱스 섹션에서는 제약 조건이 포함된 CREATE TABLE, ALTER TABLE 수정, INSERT/UPDATE/DELETE/TRUNCATE 연산, 쿼리 최적화를 위한 인덱스 생성, 쿼리 계획 분석을 위한 EXPLAIN, 외래 키 관계, 재사용 가능한 쿼리 추상화를 위한 VIEW 정의를 다룹니다.
주요 기능
- DISTINCT, WHERE, ORDER BY, LIMIT/OFFSET, LIKE 패턴 매칭, CASE WHEN을 포함한 SELECT 쿼리
- 실용적인 예제가 포함된 모든 JOIN 유형: INNER, LEFT, RIGHT, FULL OUTER, CROSS, SELF JOIN
- GROUP BY, HAVING, 윈도우 함수를 포함한 집계 함수(COUNT, SUM, AVG, MIN, MAX)
- 서브쿼리 패턴: WHERE IN, EXISTS, 파생 테이블, CTE(WITH 절), UNION/UNION ALL
- DDL 문: 제약 조건이 포함된 CREATE TABLE, ALTER TABLE, INSERT, UPDATE, DELETE, TRUNCATE
- 인덱스 관리: CREATE INDEX, 복합 인덱스, UNIQUE 인덱스, EXPLAIN 쿼리 계획 분석
- 폴백 값을 위한 COALESCE와 조건부 null 변환을 위한 NULLIF를 활용한 NULL 처리
- ON DELETE CASCADE가 포함된 외래 키 제약 조건과 재사용 가능한 쿼리 추상화를 위한 VIEW 정의
자주 묻는 질문
INNER JOIN과 LEFT JOIN의 차이점은 무엇인가요?
INNER JOIN은 두 테이블에서 일치하는 값이 있는 행만 반환합니다. LEFT JOIN은 왼쪽 테이블의 모든 행과 오른쪽 테이블의 일치하는 행을 반환하며, 일치하지 않는 오른쪽 테이블의 행은 NULL로 표시됩니다. 일치하는 레코드만 필요할 때(예: 사용자가 있는 주문) INNER JOIN을 사용하세요. 일치 여부와 관계없이 한 테이블의 모든 레코드가 필요할 때(예: 주문이 없는 사용자 포함) LEFT JOIN을 사용하세요.
GROUP BY와 HAVING은 어떻게 함께 작동하나요?
GROUP BY는 지정된 컬럼에서 동일한 값을 가진 행들을 그룹으로 축소하여 COUNT, SUM 같은 집계 함수가 그룹별로 작동하게 합니다. HAVING은 집계 이후 그룹을 필터링하며, 그룹화 전에 행을 필터링하는 WHERE와 다릅니다. 예를 들어 SELECT city, COUNT(*) FROM users GROUP BY city HAVING COUNT(*) >= 10은 10명 이상의 사용자가 있는 도시만 반환합니다. 행 수준 필터에는 항상 WHERE를, 집계 조건에는 HAVING을 사용하세요.
서브쿼리와 CTE의 차이점은 무엇인가요?
서브쿼리는 WHERE, FROM, SELECT 절 안에 중첩된 쿼리입니다. CTE(공통 테이블 표현식)는 WITH 키워드를 사용하여 메인 쿼리 전에 이름 있는 임시 결과 집합을 정의합니다. CTE는 더 읽기 쉽고, 같은 쿼리에서 여러 번 참조할 수 있으며, 재귀를 지원합니다. 서브쿼리는 단순한 일회성 사용에서 더 간결할 수 있습니다. 대부분의 데이터베이스가 둘 다 같은 방식으로 최적화하므로 성능은 일반적으로 동일합니다.
서브쿼리에서 EXISTS와 IN은 언제 사용해야 하나요?
EXISTS는 일치하는 행이 하나라도 발견되면 TRUE를 반환하고 스캔을 중지하여, 존재를 확인하는 상관 서브쿼리에 효율적입니다. IN은 전체 서브쿼리 결과 집합을 평가하고 멤버십을 확인합니다. EXISTS는 단락 평가를 하므로 대규모 서브쿼리 결과에 일반적으로 더 빠릅니다. IN은 읽기 쉽고 작은 값 목록에 더 자연스럽습니다. 관련 행의 존재를 확인할 때는 EXISTS를, 특정 값 집합으로 필터링할 때는 IN을 사용하세요.
DELETE와 TRUNCATE의 차이점은 무엇인가요?
DELETE는 행을 하나씩 제거하고, 선택적 삭제를 위한 WHERE 조건을 지원하며, 트리거를 발생시키고, 개별 행 삭제를 로깅하며, 트랜잭션에서 롤백할 수 있습니다. TRUNCATE는 모든 행을 한 번에 제거하고, WHERE를 사용할 수 없으며, 행 수준 트리거를 발생시키지 않고, 최소한의 로깅을 사용하며, 전체 테이블 비우기에 훨씬 빠릅니다. TRUNCATE는 대부분의 데이터베이스에서 자동 증가 카운터도 초기화합니다. 선택적 제거에는 DELETE를, 전체 테이블 비우기에는 TRUNCATE를 사용하세요.
인덱스는 쿼리 성능을 어떻게 향상시키나요?
인덱스는 정렬된 데이터 구조(일반적으로 B-tree)를 생성하여 데이터베이스가 전체 테이블을 스캔하지 않고 행을 찾을 수 있게 합니다. 인덱스된 컬럼에 대한 쿼리는 O(n) 전체 테이블 스캔에서 O(log n) 인덱스 조회로 변합니다. 복합 인덱스(여러 컬럼)는 해당 컬럼 순서대로 필터링하는 쿼리를 지원합니다. 그러나 인덱스는 INSERT/UPDATE/DELETE 작업을 느리게 하고 저장 공간을 소비합니다. EXPLAIN을 사용하여 쿼리가 생성한 인덱스를 실제로 사용하는지 확인하세요.
COALESCE란 무엇이며 NULL 값을 어떻게 처리하나요?
COALESCE는 인수 목록에서 첫 번째 NULL이 아닌 값을 반환합니다. COALESCE(nickname, name, "익명")는 닉네임이 있으면 닉네임을, 없으면 이름을, 그것도 없으면 "익명"을 반환합니다. SQL 표준이며 모든 데이터베이스에서 작동합니다. SELECT에서 폴백 값 제공과 WHERE 절에서 선택적 컬럼 처리에 사용하세요. NULLIF(a, b)는 a가 b와 같으면 NULL을 반환하고, 그렇지 않으면 a를 반환하며, 0으로 나누기 방지에 유용합니다: amount / NULLIF(count, 0).
VIEW란 무엇이며 언제 사용해야 하나요?
VIEW는 가상 테이블로 작동하는 저장된 SQL 쿼리입니다. CREATE VIEW active_users AS SELECT ...로 active_users를 실제 테이블처럼 쿼리할 수 있습니다. 뷰는 복잡한 쿼리를 단순화하고, 특정 컬럼만 노출하여 보안 계층을 제공하고, 애플리케이션 전반에 걸쳐 일관된 쿼리 로직을 보장하며, 쿼리를 더 읽기 쉽게 만듭니다. 뷰는 데이터를 저장하지 않으며 매번 기본 쿼리를 실행합니다. 캐시된 결과가 필요하면 지원되는 곳에서 구체화된 뷰를 사용하세요.