본문으로 바로가기
TaeyoungKim.dev

SQL DISTINCT 여러 컬럼 중복 제거: 한 컬럼이 계속 중복되는 이유

DB/SQL작성 약 3분 읽기TaeyoungKim
LinkedInX

DISTINCT를 붙였는데 Seoul이 여전히 두 줄 나온다. 중복 제거가 출근을 안 한 걸까? SQL은 일을 했다. 다만 내가 보고 있던 한 컬럼이 아니라, SELECT에 적은 컬럼들의 조합을 비교했다.

DISTINCT는 어떤 값을 비교할까?

주문 다섯 건을 놓고 보자. 1번과 2번 주문은 지역과 상태가 같고, 3번은 같은 지역이지만 상태가 다르다. id는 주문마다 고유하다.

sql
CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  region TEXT NOT NULL,
  status TEXT NOT NULL
);

INSERT INTO orders (id, region, status) VALUES
  (1, 'Seoul', 'paid'),
  (2, 'Seoul', 'paid'),
  (3, 'Seoul', 'pending'),
  (4, 'Busan', 'paid'),
  (5, 'Busan', 'pending');

지역만 선택하면 결과는 두 행이다.

sql
SELECT DISTINCT region FROM orders ORDER BY region;
-- Busan
-- Seoul

DISTINCT는 원본 테이블의 모든 컬럼을 비교하는 명령이 아니다. 선택한 결과 행에서 같은 값의 조합을 한 번만 남긴다. 여기서는 region 하나만 선택했으니 같은 지역이 합쳐진다.

DISTINCT에 여러 컬럼을 쓰면 왜 Seoul이 두 번 나올까?

이번에는 상태도 함께 선택한다.

sql
SELECT DISTINCT region, status
FROM orders
WHERE region = 'Seoul'
ORDER BY status;
-- Seoul | paid
-- Seoul | pending

그림의 왼쪽 주문 세 건은 Seoul / paid 두 건과 Seoul / pending 한 건이다. region만 보면 한 종류지만, (region, status)를 한 쌍으로 보면 서로 다른 조합 두 종류다. 그래서 Seoul이 두 줄 보인다. DISTINCT가 각 컬럼을 따로 중복 제거한 뒤 붙이는 것은 아니다.

질문이 '지역 목록'이라면 region만 선택한다. 질문이 '지역별 주문 상태 조합'이라면 두 컬럼을 선택한다. 어떤 행을 고유하다고 볼지 먼저 정해야 쿼리도 맞아진다.

SELECT DISTINCT *는 왜 효과가 없을까?

sql
SELECT DISTINCT * FROM orders;
-- 5행: id가 1, 2, 3, 4, 5로 모두 다르다.

*는 id까지 포함한다. 1번과 2번의 지역·상태가 같아도 id가 다르므로 전체 행은 중복이 아니다. 주문 ID를 표시하면서 '지역·상태만 중복 제거'하려면, 그 조합에서 어느 주문을 대표로 고를지 별도의 기준이 필요하다. DISTINCT 하나로 대표 주문이 자동 선택되지는 않는다.

조인 뒤 결과가 예상보다 많을 때도 DISTINCT *를 먼저 붙이기보다 조인 조건과 원본의 관계부터 확인하자. 잘못된 연결 때문에 늘어난 행이라면 중복 제거는 원인을 숨길 수 있다.

중복이 몇 건인지 알고 싶다면 GROUP BY

DISTINCT는 조합의 종류를 보여 준다. 같은 조합이 몇 건씩 있는지가 궁금하다면 집계한다.

sql
SELECT region, status, COUNT(*) AS orders_count
FROM orders
GROUP BY region, status
ORDER BY region, status;
-- Busan | paid    | 1
-- Busan | pending | 1
-- Seoul | paid    | 2
-- Seoul | pending | 1

Seoul / paid가 두 건이라는 사실이 이제 보인다. 종류만 필요한지, 종류별 건수까지 필요한지에 따라 DISTINCT와 GROUP BY를 고르면 된다.

핵심 요약

SELECT DISTINCT region은 지역 값으로, SELECT DISTINCT region, status는 지역과 상태의 조합으로 중복을 판단한다. Seoul이 두 줄 남아도 상태가 다르면 정상이다. *에 고유한 id가 포함되면 다섯 주문은 모두 서로 다른 행이고, 조합별 건수는 GROUP BY와 COUNT(*)로 확인한다.

작성자

TaeyoungKim

기초 개념을 구현과 검증, 실제 운영 판단까지 연결해 기록합니다.

#SQL DISTINCT#여러 컬럼 중복 제거#SELECT DISTINCT#SQL GROUP BY

함께 읽으면 좋은 글