인프런 커뮤니티 질문&답변

qwerty1434님의 프로필 이미지
qwerty1434

작성한 질문수

Real MySQL 시즌 1 - Part 1

Ep.06 Lateral Derived Table

6강. Top N 데이터 조회와 관련해 질문있습니다.

해결된 질문

작성

·

47

0

안녕하세요.
강의 마지막에 카테고리별 조회수가 가장 높은 3개 기사를 추출 하는 쿼리 소개해 주셨는데요. 관련해서 질문 있습니다.

 

Q1) 만약 categories 테이블에 id가 1,2,3인 데이터가 있다면

SELECT
FROM
WHERE category_id = 1
ORDER BY
LIMIT 3
SELECT
FROM
WHERE category_id = 2
ORDER BY
LIMIT 3
SELECT
FROM
WHERE category_id = 3
ORDER BY
LIMIT 3

이렇게 3번의 서브쿼리가 실행되고 각 결과를 전부 Union해서 최종 결과를 반환하게 되는건가요?


Q2) LIMIT 3을 제거했을 때 내림차순 정렬이 안된 상태로 데이터가 반환되는데요. 그 이유가 뭔지 알 수 있을까요?

image.png

 

답변 2

0

백은빈님의 프로필 이미지
백은빈
지식공유자

안녕하세요. 답변이 좀 늦었습니다.

질문주신 내용들에 대해 각각 답변을 드리면,

Q1) 만약 categories 테이블에 id가 1,2,3인 데이터가 있다면, 3번의 서브쿼리가 실행되고 각 결과를 전부 Union해서 최종 결과를 반환하게 되는건가요?

대략 말씀하신 형태로 동작한다고 보시면 되는데요, 독립적으로 실행되는 서브쿼리보다는 조인과 같은 형태로 처리된다고 생각해주시면 좋을 것 같습니다.

Q2) LIMIT 3을 제거했을 때 내림차순 정렬이 안된 상태로 데이터가 반환되는데요. 그 이유가 뭔지 알 수 있을까요?

이건 쿼리의 실행계획을 봐야하는데요. LIMIT 절이 있을 때는 (category_id, views)로 구성된 인덱스를 뒤에서부터 읽다보니(Backward index scan) 내림차순 정렬로 데이터가 반환됐지만 LIMIT 절이 없는 경우에는 해당 인덱스를 정순으로 스캔하면서 데이터를 읽어와서 오름차순 정렬인 것으로 예상됩니다.

사실 이 부분은 현재 제일 바깥쪽 쿼리에 ORDER BY 절이 없기때문에, 쿼리 처리 방식에 따라 최종적인 결과 데이터의 정렬 순서가 예상한 것과는 다를 수 있습니다. 그래서 어떻게 처리되던지 항상 내림차순 정렬을 원하시면 제일 바깥쪽 쿼리에 ORDER BY 절을 명시해주시는 것이 좋습니다.

 

답변 읽어보시고 혹시 더 추가로 궁금한 부분 있으시면 말씀해주세요!

감사합니다.

qwerty1434님의 프로필 이미지
qwerty1434
질문자

어떤 내용인지 이해했습니다. 답변 감사합니다~!!

0

안녕하세요, 인프런 AI 인턴입니다.

qwerty1434님께서 문의주신 내용에 대해 답변드립니다.

Q1) 카테고리별 조회수가 가장 높은 3개 기사를 추출 쿼리의 동작 원리

말씀해주신 카테고리별 조회수가 가장 높은 3개 기사를 추출하는 쿼리는 현대적인 SQL에서는 구체적으로 쿼리에 따라 다양한 방식으로 구현될 수 있습니다. 특히 최신 SQL 표준에서는 윈도우 함수와 Common Table Expressions (CTEs)을 활용하면 더 간단하게 작성할 수 있습니다.

하지만, 기본적인 방식으로 이해하시려면 서브쿼리를 통해 카테고리별로 3개 기사를 추출하는 예를 들 수 있습니다. 이때, 각 카테고리에 대해 서브쿼리가 실행되고, 그 결과를 전부 UNION으로 합쳐 최종 결과가 반환됩니다.

WITH category_ranking AS (
    SELECT
        c.name,
        t.title,
        t.views,
        ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY t.views DESC) as rank
    FROM
        categories c
    INNER JOIN
        articles t ON c.id = t.category_id
)
SELECT
    name,
    title,
    views
FROM
    category_ranking
WHERE
    rank <= 3
ORDER BY
    name, views DESC;

위 쿼리는 각 카테고리별로 조회수를 기준으로 랭크를 매기고, 각각의 카테고리에서 상위 3개의 기사를 조회합니다.

Q2) LIMIT 3 제거 시 내림차순 정렬이 안되는 이유

LIMIT 3을 제거했을 때 내림차순 정렬이 유지되지 않는 이유는 다음과 같습니다. LIMIT 절은 특정 개수의 행만을 반환하기 때문에 정렬된 결과에서 상위 N개의 행만을 선택할 수 있습니다. 이를 제거하면 전체 결과 집합이 정렬되지 않은 것처럼 보일 수 있습니다. 이는 데이터베이스 엔진이 최종 결과 셋을 정렬할 필요가 없다고 판단해서 발생할 수 있습니다.

올바른 정렬과 관계없이 모든 결과를 원하실 경우, ORDER BY 절을 제대로 사용하여 전체 결과를 정렬해야 합니다:

SELECT
    c.name,
    t.title,
    t.views
FROM
    categories c
INNER JOIN
    articles t ON c.id = t.category_id
ORDER BY
    c.name, t.views DESC;

위 예제에서는 각 카테고리의 이름과 그에 속한 기사를 조회수에 따라 내림차순으로 정렬합니다.

qwerty1434님의 질문에 대한 추가 설명이나 이해를 돕기 위해 관련 유사 질문 또한 확인해 보실 수 있습니다:

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

qwerty1434님의 프로필 이미지
qwerty1434

작성한 질문수

질문하기