해결된 질문
작성
·
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을 제거했을 때 내림차순 정렬이 안된 상태로 데이터가 반환되는데요. 그 이유가 뭔지 알 수 있을까요?
답변 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
절을 명시해주시는 것이 좋습니다.
답변 읽어보시고 혹시 더 추가로 궁금한 부분 있으시면 말씀해주세요!
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
qwerty1434님께서 문의주신 내용에 대해 답변드립니다.
말씀해주신 카테고리별 조회수가 가장 높은 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개의 기사를 조회합니다.
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님의 질문에 대한 추가 설명이나 이해를 돕기 위해 관련 유사 질문 또한 확인해 보실 수 있습니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
어떤 내용인지 이해했습니다. 답변 감사합니다~!!