SQL 심화 기술 — Upsert, PIVOT, 샤딩, Sargability
80 SQL Interview Questions for Data Engineers (Real Asks, 2026) — DataVidhya blog Technical Deep Dive, Q41-50 (pp.17-20)
이 모듈을 다 읽으면
- Upsert 개념과 엔진별 구현 방언(MERGE, ON CONFLICT, ON DUPLICATE KEY)의 차이를 설명할 수 있다
- Full Outer Join, 상관 서브쿼리, PIVOT의 동작 원리를 설명할 수 있다
- 샤딩과 파티셔닝의 차이를 구분할 수 있다
- Sargability 개념과 인덱스를 무력화하는 안티패턴을 식별할 수 있다
Upsert의 엔진별 구현 차이, Full Outer Join과 상관 서브쿼리, 데이터 프로파일링, PIVOT, 샤딩, 그리고 실무에서 자주 놓치는 Sargability 개념까지 SQL 심화 주제를 다룬다.
Upsert — Update와 Insert의 합성어
'Upsert'는 Update와 Insert의 합성어로, 고유 키를 기준으로 기존 레코드를 갱신하려고 시도하되 그 키가 없으면 대신 새 레코드를 삽입하는 데이터베이스 연산이다.
— 정정: 원문은 '표준 SQL에서는 보통 MERGE 문으로 구현한다'고만 설명하지만, 실제로는 엔진마다 관용적인 Upsert 문법이 다르다. MERGE는 SQL:2003 표준에 포함된 방식으로 SQL Server, Oracle, Snowflake, BigQuery 등에서 널리 쓰인다. 반면 PostgreSQL은 `INSERT ... ON CONFLICT (key) DO UPDATE`가 관용적인 Upsert 방식이며(PostgreSQL 15부터 MERGE도 지원하지만 ON CONFLICT가 여전히 더 흔하게 쓰인다), MySQL은 `INSERT ... ON DUPLICATE KEY UPDATE`를 쓴다. 인터뷰나 실무에서는 '어떤 엔진 기준인지'를 먼저 명시하는 것이 정확한 답변이다.
핵심 포인트
- Upsert는 키가 있으면 UPDATE, 없으면 INSERT하는 연산이다.
- MERGE는 SQL:2003 표준 방식(SQL Server/Oracle/Snowflake/BigQuery)이지만, PostgreSQL은 ON CONFLICT, MySQL은 ON DUPLICATE KEY UPDATE가 관용적으로 쓰인다 — 정정.
날짜 변환, Full Outer Join, 데이터 프로파일링
문자열을 날짜로 변환하는 문법은 SQL 방언마다 다르다. PostgreSQL은 `TO_DATE(string, format)`, SQL Server는 `CONVERT(DATE, string)`을 쓰고, Snowflake나 BigQuery 같은 현대적 웨어하우스는 `string::DATE`나 `CAST(string AS DATE)` 같은 단순 캐스팅을 지원한다.
Full Outer Join은 Left Outer Join과 Right Outer Join의 결과를 합친 것으로, 양쪽 테이블의 모든 레코드를 반환하며 매칭되는 곳은 조인하고 매칭되지 않는 쪽은 NULL로 채운다.
데이터 프로파일링은 새로운 데이터셋을 SQL로 탐색하고 이해하는 과정이다. NULL 비율 계산, 값의 분포(최솟값/최댓값/평균) 파악, 고유값 개수 확인, 잠재적 데이터 품질 이슈 발견 등이 파이프라인을 만들기 전 필수적으로 수행하는 작업이다.
핵심 포인트
- 날짜 캐스팅 문법은 엔진마다 다르다(PostgreSQL: TO_DATE, SQL Server: CONVERT, Snowflake/BigQuery: CAST 또는 ::DATE).
- Full Outer Join은 양쪽 테이블의 모든 행을 반환하고 매칭 안 되는 쪽은 NULL로 채운다.
- 데이터 프로파일링은 파이프라인 구축 전 NULL 비율, 값 분포, 고유값 개수를 파악하는 탐색 작업이다.
PIVOT과 샤딩
행을 열로 바꾸는 PIVOT은 SQL Server, Snowflake 같은 일부 방언에 내장 PIVOT 연산자로 제공된다. PIVOT이 없는 방언에서는 집계 함수와 CASE 문을 조합해 같은 효과를 낸다 — 예: `SUM(CASE WHEN category = 'A' THEN amount ELSE 0 END)`.
— 보강: BigQuery Standard SQL도 PIVOT 연산자를 지원한다(원문은 SQL Server와 Snowflake만 언급했으나, BigQuery 역시 PIVOT을 제공한다).
샤딩(Sharding)은 데이터를 여러 개의 독립된 데이터베이스 인스턴스(샤드)에 수평으로 분산하는 확장 기법이다. 각 샤드는 동일한 스키마를 갖지만 서로 다른 데이터 부분집합을 보유한다(예: A-M 사용자는 샤드 1, N-Z 사용자는 샤드 2). 이는 한 대의 서버가 감당할 수 있는 것보다 더 많은 트래픽을 처리할 수 있게 해준다 — 참고로 이는 03번 모듈에서 다룬 '파티셔닝'(한 데이터베이스 안에서 테이블을 물리적으로 나누는 것)과는 다른 개념으로, 샤딩은 아예 별도의 데이터베이스 인스턴스로 분산한다는 점이 차이다.
핵심 포인트
- PIVOT은 SQL Server, Snowflake, BigQuery 등에서 내장 연산자로 제공되며, 없는 방언에서는 집계+CASE 조합으로 구현한다.
- 샤딩은 데이터를 여러 독립된 데이터베이스 인스턴스로 수평 분산하는 것으로, 한 DB 내 파티셔닝과는 다른 개념이다.
임시 테이블 vs 테이블 변수, Sargability
임시 테이블과 테이블 변수를 비교하는 질문은 사실상 SQL Server(T-SQL)에 특화된 개념이다 — 다른 엔진(PostgreSQL, MySQL)에는 임시 테이블(TEMPORARY TABLE)은 있지만 '테이블 변수'라는 별도의 구분된 구성 요소는 없다. SQL Server 맥락에서 임시 테이블은 물리적 임시 저장소에 생성되어 인덱스를 지원하고 세션 전체에서 보이는 반면, 테이블 변수는 보통 메모리에 저장되고 범위가 더 제한적이며(현재 배치나 프로시저 내), 아주 작은 데이터셋에서는 성능이 더 나은 경향이 있다.
Sargability(Search ARGument ABLE)는 쿼리가 인덱스를 활용할 수 있는지를 가리키는 개념이다. `WHERE LEFT(name, 1) = 'A'`처럼 WHERE 절의 컬럼을 함수로 감싸는 것이 대표적인 sargability를 깨뜨리는 안티패턴이다 — 이렇게 하면 데이터베이스가 name 컬럼의 인덱스를 활용하지 못하고 매 행마다 함수를 실행하며 전체 스캔을 하게 된다.
핵심 포인트
- '임시 테이블 vs 테이블 변수' 구분은 SQL Server(T-SQL)에 특화된 개념이며 다른 엔진에는 없다.
- Sargability는 쿼리가 인덱스를 쓸 수 있는지를 뜻하며, WHERE 절에서 컬럼을 함수로 감싸는 것이 대표적으로 이를 깨뜨린다.