메인 콘텐츠로 건너뛰기

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
SELECT DISTINCT는 각 결과 행을 몇 번 나타나든 한 번만 반환합니다. “이 열에 어떤 값이 나타나는가”라는 형태의 질문에 답하는데, 처음 만나는 테이블에 대해 가장 먼저 알고 싶은 것이 흔히 이것입니다. 시작하기 전에 mysql -u root -p sakila로 클라이언트를 여세요.

DISTINCT의 동작 방식

COLUMN_LIST를 원하는 열로, TABLE_NAME을 테이블로 바꾸세요. DISTINCT는 SELECT 바로 뒤에 오고, 옆에 있는 열이 아니라 SELECT 목록 전체에 적용됩니다. 이 한 가지 사실이 DISTINCT에 관한 대부분의 놀라움을 설명합니다.

예제

  1. 한 열에 있는 값

Sakila는 모든 영화에 등급을 매깁니다. 이 쿼리는 어떤 등급이 존재하는지 묻습니다.
1,000편의 영화에 5개의 등급입니다. 쓸모 있는 순서 없이 도착하는데, DISTINCT는 중복을 제거할 뿐 순서에 대해서는 아무것도 말하지 않기 때문입니다. 순서를 원하면 ORDER BY를 추가하세요.

  1. 다른 열

카탈로그의 모든 영화는 3가지 요금 중 하나로 가격이 매겨져 있습니다.

  1. 고유한 조합

2개의 열 이름을 쓰면 각 열의 값을 따로 얻는 것이 아니라 고유한 쌍 각각을 얻습니다.
5개의 등급 곱하기 3개의 요금은 15이고, 모든 조합이 실제로 나타납니다.

정렬된 등급이 알파벳순이 아닌 이유

그 결과는 rating으로 정렬되었는데도 G, PG, PG-13, R, NC-17 순입니다. 알파벳순이라면 NC-17이 두 번째에 와야 합니다. ORDER BY는 제대로 동작했고, 이유는 열의 유형입니다: SHOW COLUMNS는 테이블의 열을 나열하고, LIKE 뒤의 패턴이 그것을 1개의 이름으로 좁힙니다.
rating은 ENUM으로, 고정된 값 목록만 받는 열 유형입니다. MySQL은 각 값을 그 목록 안의 위치로 저장하고 위치로 정렬하므로, ENUM은 값이 선언된 순서로 정렬됩니다. 여기서는 선언 순서가 가장 덜 제한적인 등급에서 가장 제한적인 등급으로 이어집니다.

열을 추가하면 효과가 사라질 수 있습니다

DISTINCT는 행 전체를 보기 때문에, 거의 고유한 열을 추가하면 거의 아무것도 제거되지 않습니다.
1,000개의 행이 모두 돌아옵니다. 제목이 모두 다르므로 rating과 title의 쌍도 모두 다르고, 어느 것도 중복이 아닙니다. 여기서 DISTINCT는 5개의 행을 줄 수 없는데, 1,000개의 서로 다른 값이 든 열을 요구했기 때문입니다. 많은 행을 등급당 1개로 접는 것은 다른 연산이고, GROUP BY가 그것을 위한 절입니다.

요약

  • 각 결과 행을 한 번만 반환하려면 SELECT DISTINCT를 쓰세요.
  • SELECT 목록의 모든 열에 한꺼번에 적용된다고 예상하세요.
  • 고유한 값을 정렬하고 싶으면 ORDER BY를 추가하세요.
  • ENUM 열은 알파벳순이 아니라 선언된 순서로 정렬된다고 예상하세요.

함께 보기

  • SELECT — DISTINCT가 수식하는 문
  • ORDER BY — 고유한 값 정렬하기
  • GROUP BY — 행을 값당 1개로 접고 개수 세기