오늘은 중복된 결과를 제거하기 위해 mysql에서 많이 써먹는 distinct 절에 대해 알아보도록 하겠습니다.

 


 world에서, country 테이블을 생각해 봅시다. 나라는, Continent라는 컬럼도 포함할 겁니다. 예를 들어, 아시아, 유럽, 북아메리가 등등. country에서, Continent만 뽑아 봅시다.

 

 

 그러면 쿼리는 위와 같이 작성하면 됩니다. 그런데, 이것은 country에 있는 레코드를 모두 뽑아냅니다. 물론, 속성은 Continent만 뽑아내겠지만요. 예를 들어서, 영국과 프랑스가 있다면, "Europe" 이라는 것은 2번 이상 뽑힐 겁니다.

 

 

 그런가요? 저는, country 테이블에 있는 나라들이 속해있는 대륙의 갯수만 알고 싶습니다. 즉, Europe이 2번 나온다면 1번만 세야 합니다. 어떻게 하면 좋을까요?

 

 

 Continent를 distinct하게 뽑으면 됩니다. 즉, 위와 같은 쿼리를 작성하시면 됩니다.

 

 

 그러면, 위와 같은 결과가 나올 거에요.

 

 


 이제, sakila에서, rental 테이블을 고려해 봅시다. 이것은, 고객이 주문을 한 정보가 모두 들어있을 거에요. 그러면, 이런 쿼리를 생각해 봅시다. 영화 film을 빌린, 고객의 수가 몇 명인지 구해주세요.

 

 

 이런 쿼리를 작성하면 어떨까요? 기본적으로 where 절이 없기 때문에, rental 테이블에 있는 전체 row (레코드)의 갯수가 나올 거에요. 그런데 잘 생각해 봅시다. 고객 1명이 film 하나만 빌릴 수 있나요? 아. 너무 옛날 이야기인가요? 편의점에서 물건을 살 때, 1번만 딱 사고 안 가나요? 그건 아닙니다. 즉, 고객 1명이 여러 개의 주문을 할 수 있습니다.

 

 따라서, 같은 고객이 여러번 결과값에 나올 수 있습니다.

 

 

 아. 정말 골치 아프네요. 그러면 어떻게 해야 할까요?

 

 

 customer_id를 distinct하게 뽑으면 됩니다.

 

 

 그러면, 고객이 여러 번 주문을 했어도, 1번만 뽑힙니다. 그러면 2005년 6월 1일 이전에 빌린 고객의 수는 어떻게 구하면 좋을까요?

 

 

 간단하게 unix_timestamp 함수를 이용해서 처리하면 됩니다. rental 테이블에서 선택을 하는데, 필터링 조건으로, 2005년 6월 1일 이전의 주문만 선택이 됩니다. 다음에, 그 레코드에 있는 customer_id의 속성만 결과값에 나타나는데요. id가 중복되서 나타나면 제거됩니다.

 

 2005년 6월 1일 이전의 데이터만 나온다는 것이 1차 필터링 조건입니다.

 

 

 결과를 오름차순으로 정렬하면 위와 같이 나옵니다.

 


 이제 film 테이블을 가지고 정보를 하나 뽑아보도록 하겠습니다.

 

 

 각 영화에는 등급이 있습니다. 10세 이상 관람, 12세 이상 관람. 혹은 연령 제한 없음. rating 속성만 film 테이블에서 뽑아보니, 아래와 같이 나옵니다.

 

 

음. 대충 요렇게 나오는군요. 그러면, distinct(rating)을 하면, film 테이블에 있는 등급의 종류 수가 나올 거에요.

 

 

 그러면, 이렇게 작성하시면 될 거에요.

 

 

 위 결과에서는 5개만 나오네요. 생각보다, rating 종류가 적다는 것을 알 수 있어요.

 

 


 이제 돛단배 교과서에 나오는 학교 데이터 베이스를 생각해 봅시다. 학교에서 여태까지 개설이 된 과목들을 모두 구해주세요. 그런데, 과목은 과목명이 표시되게 하고 싶습니다. section 테이블에는 과목명이 없고 과목 코드만 있는 상황입니다. 그리고, course에 과목명이 있습니다.

 

 

 그러면 먼저, section하고 course하고 natural join을 합니다.

 

 

 여기서, title을 distinct하게 뽑으면 될 거에요.

 

 

  그러면, 아래와 같이 결과가 나옵니다.

 

 

 그런데, 이런 경우를 생각해 봅시다. 1학기와 2학기 때 배우는 공학수학 내용이 다른데, 과목명과 과목 코드가 모두 같은 경우. 이 때에는 어떤가요? 이 때에는, 단순히 distinct(title)이나, distinct(course_id)로 처리하면 잘못된 결과를 리턴하게 됩니다. 그러면 어떻게 해야 하나요?

 

 조건을 2개를 걸어버리면 됩니다. title과 sec_id 두 개 모두가 같다면 중복 처리를 하겠다.

 

 

 그러면, 이렇게 쿼리를 작성하면 됩니다.

 

 

 Visual BASIC이라는 과목은 1학기, 2학기 때 개설이 되어 있다는 정보가 있다는 것을 알 수 있습니다.