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에 관한 대부분의 놀라움을 설명합니다.
예제
- 한 열에 있는 값
Sakila는 모든 영화에 등급을 매깁니다. 이 쿼리는 어떤 등급이 존재하는지 묻습니다.
DISTINCT는 중복을 제거할 뿐 순서에 대해서는 아무것도 말하지 않기 때문입니다. 순서를 원하면 ORDER BY를 추가하세요.
- 다른 열
- 고유한 조합
2개의 열 이름을 쓰면 각 열의 값을 따로 얻는 것이 아니라 고유한 쌍 각각을 얻습니다.
정렬된 등급이 알파벳순이 아닌 이유
그 결과는rating으로 정렬되었는데도 G, PG, PG-13, R, NC-17 순입니다. 알파벳순이라면 NC-17이 두 번째에 와야 합니다. ORDER BY는 제대로 동작했고, 이유는 열의 유형입니다:
SHOW COLUMNS는 테이블의 열을 나열하고, LIKE 뒤의 패턴이 그것을 1개의 이름으로 좁힙니다.
rating은 ENUM으로, 고정된 값 목록만 받는 열 유형입니다. MySQL은 각 값을 그 목록 안의 위치로 저장하고 위치로 정렬하므로, ENUM은 값이 선언된 순서로 정렬됩니다. 여기서는 선언 순서가 가장 덜 제한적인 등급에서 가장 제한적인 등급으로 이어집니다.
열을 추가하면 효과가 사라질 수 있습니다
DISTINCT는 행 전체를 보기 때문에, 거의 고유한 열을 추가하면 거의 아무것도 제거되지 않습니다.
rating과 title의 쌍도 모두 다르고, 어느 것도 중복이 아닙니다. 여기서 DISTINCT는 5개의 행을 줄 수 없는데, 1,000개의 서로 다른 값이 든 열을 요구했기 때문입니다. 많은 행을 등급당 1개로 접는 것은 다른 연산이고, GROUP BY가 그것을 위한 절입니다.
요약
- 각 결과 행을 한 번만 반환하려면
SELECT DISTINCT를 쓰세요. - SELECT 목록의 모든 열에 한꺼번에 적용된다고 예상하세요.
- 고유한 값을 정렬하고 싶으면
ORDER BY를 추가하세요. ENUM열은 알파벳순이 아니라 선언된 순서로 정렬된다고 예상하세요.