본문 바로가기
CS/DataBase

DISTINCT와 ORDER BY를 같이 사용할 경우 정렬이 제대로 되지 않는 현상 해결

by yongckim 2022. 8. 30.
728x90
반응형

책을 기반으로 스터디를 만드는 웹 애플리케이션을 만드는 프로젝트 진행하던 중 최근에 스터디가 생성된 책을 조회하는 쿼리를 짜게 되었습니다.

(아래는 해당 프로젝트 깃허브입니다.)

https://github.com/prgrms-web-devcourse/Team-Books-CheckMoi-BE

 

GitHub - prgrms-web-devcourse/Team-Books-CheckMoi-BE: 도서 기반 스터디 관리 플랫폼 - CheckMoi

:book: 도서 기반 스터디 관리 플랫폼 - CheckMoi. Contribute to prgrms-web-devcourse/Team-Books-CheckMoi-BE development by creating an account on GitHub.

github.com

현재 책 정보를 저장한 테이블인 book과 스터디 정보를 저장한 study 테이블이 다음과 같이 존재하는 형태입니다.

여기서 책을 스터디가 개설된 순으로 정렬하여 보내주는 쿼리를 작성하게 되었습니다.

같은 책으로 스터디를 개설할 수 있기 때문에 중복되는 책을 제거하고 스터디 생성순으로 정렬하기 위해 다음과 같이 쿼리를 작성했습니다.

SELECT DISTINCT book.* FROM book
JOIN study s on book.id = s.book_id
ORDER BY s.created_at desc;

 

제가 예상한 동작은 ORDER BY를 통해 최신순으로 정렬하고 DISTINCT로 중복된 책 정보가 제거되는 상황을 생각했습니다.

하지만 제가 원하는바와 달리 스터디 생성순서가 아닌 이상한 순서로 책이 반환되었습니다.

원인 분석 과정

무언가 순서가 이상한 것을 느끼고 먼저 최근 개설된 스터디의 책 ID를 확인해보았습니다.

SELECT study.book_id FROM study
ORDER BY study.created_at desc
LIMIT 5;

그런데 제가 작성한 쿼리는 다음과 같이 나오는 것을 확인했습니다.

SELECT DISTINCT book.* FROM book
JOIN study s on book.id = s.book_id
ORDER BY s.created_at desc;

결과를 확인해보니 DISTINCT가 먼저 중복을 다 제거한 후 그중에서 ORDER BY로 정렬해서 문제가 생겼다는 것을 알았습니다.

DISTINCT로 제거되는 행에 최근 생성된 스터디가 개설된 책이 사라져서 정렬이 제가 원하는 방향으로 되지 않았던 것입니다.

SQL의 각 명령의 실행순서는 다음과 같기 때문에 주의해야 한다는 사실을 깨달았습니다.

먼저 WHERE이 실행되고, 그다음에 SELECT가 실행되고 마지막으로 ORDER BY에 해당되는 구문이 실행됩니다.

이때문에 현재 작성한 쿼리로는 현재 원하는 최근에 스터디가 생성된 책을 조회하는 쿼리 작성이 불가능하다는 것을 깨달았고 쿼리를 새로짜게 되었습니다.

GROUP BY를 통한 중복 제거

 DISTINCT로는 쿼리 실행 순서 때문에 해결이 불가능하기에 GROUP BY로 이를 해결했습니다.

먼저, 중복을 제거하기 위해 책의 ID 값을 기준으로 group by로 묶은 후 집계함수를 이용하여 묶은 책들중 가장 최근에 스터디가 개설된 책을 기준으로 정렬하게 쿼리를 다음과 같이 작성했습니다.

SELECT *, max(s.created_at) AS created_study FROM book
JOIN study s on book.id = s.book_id
GROUP BY s.book_id
order by created_study desc;

실행 결과를 확인해보면 다음과 같이 최근 스터디가 개설된 책을 기준으로 잘 조회되는 것을 확인했습니다.

정리

  • DISTINCT와 ORDER BY를 혼용해서 사용할 경우 쿼리 실행순서때문에 자신이 원하는 결과값을 얻지 못할 수 있습니다.
  • SQL 쿼리는 WHERE -> SELECT -> ORDER BY 순으로 실행된다.
  • GROUP BY를 사용해서 중복제거를 한 후 정렬을 하려면 집계함수를 사용해야 정상적으로 정렬할 수 있다.

참고자료

How SQL DISTINCT and ORDER BY are Related

 

How SQL DISTINCT and ORDER BY are Related

One of the things that confuse SQL users all the time is how DISTINCT and ORDER BY are related in a SQL query. The Basics Running some queries against the Sakila database, most people quickly under…

blog.jooq.org

반응형