본문 바로가기

Data Literacy/SQL

Chapter 1. 데이터 조회, 필터링(3) - SELECT DISTINCT

postgreSQL logo image

 

 

이번 아티클에서는 SELECT DISTINCT 문을 배워보도록 하겠습니다. 지금까지 다룬 명령어에 비해서 살짝 난이도가 올라가는 부분이니, 꼼꼼하게 내용을 살펴보도록 하겠습니다. 

 

SELECT DISTINCT는 한마디로 요약하면 [중복제거]입니다. 그 이상의 별다른 의미는 없죠. 간단합니다. 엑셀에서도 '중복제거'와 관련된 기능이 있는데, SQL에서도 동일한 기능을 쿼리를 통해서 구현한다는 차이점만 있을 뿐입니다. 앞서 배운 ORDER BY 내용까지 잘 기억하고 있다면 큰 어려움은 없을 것입니다. 

 

 


 

 

 

○ 중복제거 테스트 용 테이블 T1 생성 

 

우선 중복제거 SELECT DISTINCT의 원활한 실습을 위해서, 임의의 테이블을 만들어 보겠습니다. 중복제거 명령어 학습에 딱 맞는 테이블을 만들고, 이 테이블을 대상으로 SELECT DISTINCT 명령어를 실행하겠습니다. 테이블 생성 명령어는 일단 기본적인 내용만 살펴보고 상세 내용은 추후 데이터베이스 생성 관련 내용을 학습하면서 살펴보도록 하겠습니다.

 

우선 아래 명령어를 통해, 현재 실습 중인 dvdrental DB안에 세 개의 칼럼을 가진 테이블 T1을 생성합니다.

create table t1 (ID SERIAL not null primary key, bcolor varchar, fcolor varchar);

select * from t1;

 

테이블 t1이 생성되었습니다

 

 

 

이제 생성된 테이블 t1의 bcolor, fcolor 칼럼에 각각 다음 데이터를 insert 해보겠습니다. id는 데이터 생성에 따라 자동으로 부여되는 값이니 별도로 입력하지는 않습니다. 

 

insert into t1 (bcolor, fcolor) 
	values
		('red', 'red')
		,('red', 'red')
		,('red', null)
		,(null, 'red')
		,('red', 'green')
		,('red', 'blue')
		,('green', 'red')
		,('green', 'blue')
		,('green', 'green')
		,('blue', 'red')
		,('blue', 'green')
		,('blue', 'blue');

 

이제 t1 테이블 전체를 출력해 보면, 다음과 같은 결과를 확인할 수 있습니다. 

 

데이터 삽입이 완료된 t1 테이블

 

 

이제 이 t1 테이블을 이용해서 SELECT DISTINCT 명령어를 실습해 보겠습니다. 

 

 


 

 

아래와 같이 t1의 bcolor 칼럼을 기준으로 데이터를 출력하되, bcolor의 데이터 중 중복되는 행은 제거하고 남은 결과를 bcolor의 오름차순으로 정렬하는 명령어를 입력해 보겠습니다. 

 

select 
	distinct bcolor 
	from t1 
	order by bcolor

 

 

 

위와 같이 bcolor 칼럼을 출력하되 중복된 값을 제거하고, blue / green / red / null만 출력되었습니다. 

 

 


 

 

위의 쿼리에서 한 개의 칼럼을 DISTINCT에 입력하였습니다. 그럼, 두 개의 칼럼을 DISTINCT에 입력하면 어떻게 중복 제거 처리가 이루어질까요? 결론만 얘기하면 "두 개의 칼럼 모두 중복되는 값이 있는 행"을 제거하게 됩니다. 쉽게 말해 bcolor와 fcolor 칼럼의 값이 모두 똑같은 행이 있다면, 그 행만 제거하는 것이지요. 1행과 2행이 각각 (a,a) (a,a)라면 2행이 제거되는 것입니다. 실제로 예제를 실행해 보겠습니다. 

 

select 
	distinct bcolor, fcolor
	from t1
	order by bcolor, fcolor

 

위의 결과를 예측해 봅시다. 어떤 행이 제거될 것인가? 그리고 order by에 따라 어떤 순서로 데이터가 정렬될 것인가?를 예측해 보시기 바랍니다. 

 

 

 

원 데이터의 1행과 2행이 모두 'red, red' 였습니다. 그래서 그중 1개의 행이 삭제되고 11개의 행만이 남게 되었습니다. 두 개의 칼럼 값이 모두 같은 행이 중복제거 되었다는 사실을 다시 한번 기억하시기를 바랍니다. 

 

또한, ORDER BY 입력 값이 bcolor, fcolor 두 개였습니다. 이 경우 정렬은 기본적으로 오름차순이 적용됩니다. 그런데 칼럼 두 개가 입력되었을 때는 우선 첫 번째 칼럼인 bcolor를 오름차순으로 정렬합니다. blue > green > red > null 순서로 배치되었죠. 그리고 각각의 blue로 정렬된 fcolor가 다시 blue > green > red > null 순으로 정렬되었습니다. 

 

 

 


 

 

참고로 많이 사용하지는 않지만 알아두기만 하면 되는 기능인 SELECT DISTINCT ON 기능에 대해서도 간단히 알아보겠습니다. 이 기능은, 간단하게 설명하자면 두 개 이상의 칼럼을 대상으로 합니다. 그런데 한 개의 칼럼을 기준으로 중복 제거를 합니다.

 

이때 제거 방식은 한 개의 칼럼에서 중복제거를 한 것과 같은 방식으로 동작합니다. 하지만 두 번째 칼럼에도 값이 출력되어야 하죠? 그럼 두 번째 칼럼에는 어떤 값을 남기고 제거되어야 할지가 결정되어야 합니다. 이때, ORDER BY에서 선언된 방식에 따라 두 번째 칼럼에 남길 값들이 정해집니다. 

 

만일 오름 차순으로 ORDER BY가 선언되었다면, 두 번째 칼럼에서 가장 낮은 값들을 우선 남기게 되고 내림 차순이라면 가장 높은 값들을 우선 남기게 됩니다. 

 

잘 이해가 가지 않는다면 t1 테이블에서 SELECT DISTINCT ON을 실행해 보겠습니다. 

 

select 
	distinct on (bcolor) bcolor, fcolor
	from t1
	order by bcolor, fcolor

 

 

우선 괄호친 기준인 bcolor에 따라 중복을 제거하였고, fcolor는 정렬 기준에 따라 가장 낮은 blue, 그리고 null 중에서는 가장 낮은 red가 출력되었습니다. 

 

반대로 ORDER BY에 DESC를 적용해 fcolor에서 내림차순을 기준으로 중복 제거된 이후의 값을 남길 수도 있습니다. 

 

select 
	distinct on (bcolor) bcolor, fcolor
	from t1
	order by bcolor, fcolor desc