본문으로 이동
ChatRound
  1. ChatRound
  2. 예시
  3. 코드

부서별 급여 상위 3개 금액을 받는 직원 뽑기: AI가 쓴 SQL 검토

Gemini 2.5 Flash-Lite는 RANK()와 DENSE_RANK() 둘 다 된다고 했습니다. 검토 결과 이 요구사항에는 DENSE_RANK()만 맞습니다.

예시아래 답변은 이 페이지를 위해 Gemini 2.5 Flash-Lite에게 Google API로, 웹 검색 없이 쓰게 한 것입니다. 누군가의 실제 대화가 아닙니다. ChatRound가 2026년 10월 27일에 검토했습니다.검토는 이 회사의 답변에 ChatRound가 기본으로 고르는 두 모델이 했습니다.

Gemini 2.5 Flash-Lite의 답변 employees(id, name, department_id, salary) 테이블에서 부서별로 급여 상위 3위 안에 드는 금액을 받는 직원을 모두 뽑는 SQL을 작성해 주세요. 급여가 같은 사람이 여러 명이면 모두 포함해야 해요.

부서별 급여 상위 3위 직원을 모두 포함하는 SQL 쿼리

다음은 employees 테이블에서 부서별로 급여 상위 3위 안에 드는 직원을 모두 포함하는 SQL 쿼리입니다. 급여가 같은 사람이 여러 명일 경우 모두 포함하도록 RANK() 또는 DENSE_RANK() 윈도우 함수를 사용합니다.

1. RANK() 함수를 사용한 방법

RANK() 함수는 동일한 값에 대해 동일한 순위를 부여하지만, 동일한 순위가 나타날 경우 다음 순위는 건너뜁니다. 따라서 급여가 동일한 경우에도 상위 3위의 "순위"를 기준으로 하기 때문에, 같은 급여를 받는 여러 명의 직원이 3위 안에 포함될 수 있습니다.

WITH RankedEmployees AS (
    SELECT
        id,
        name,
        department_id,
        salary,
        RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) as salary_rank
    FROM
        employees
)
SELECT
    id,
    name,
    department_id,
    salary
FROM
    RankedEmployees
WHERE
    salary_rank <= 3;

설명:

  1. WITH RankedEmployees AS (...): Common Table Expression (CTE)을 사용하여 중간 결과를 정의합니다.
  2. SELECT id, name, department_id, salary, RANK() OVER (...) as salary_rank FROM employees: employees 테이블에서 필요한 컬럼을 선택하고 RANK() 윈도우 함수를 적용합니다.
    • PARTITION BY department_id: 각 부서별로 순위를 매기도록 파티션을 나눕니다.
    • ORDER BY salary DESC: 각 부서 내에서 급여가 높은 순서대로 정렬합니다.
    • as salary_rank: 계산된 순위에 salary_rank라는 별칭을 부여합니다.
  3. SELECT id, name, department_id, salary FROM RankedEmployees WHERE salary_rank <= 3: CTE RankedEmployees에서 salary_rank가 3 이하인 모든 행을 선택합니다. 이렇게 하면 각 부서별로 급여 상위 3위 안에 드는 모든 직원이 포함됩니다.
2. DENSE_RANK() 함수를 사용한 방법

DENSE_RANK() 함수는 RANK() 함수와 마찬가지로 동일한 값에 대해 동일한 순위를 부여하지만, 동일한 순위가 나타나도 다음 순위를 건너뛰지 않고 연속적으로 부여합니다. 이 경우에도 급여가 동일한 경우 3위 안에 모두 포함됩니다.

WITH RankedEmployees AS (
    SELECT
        id,
        name,
        department_id,
        salary,
        DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) as salary_rank
    FROM
        employees
)
SELECT
    id,
    name,
    department_id,
    salary
FROM
    RankedEmployees
WHERE
    salary_rank <= 3;

설명:

DENSE_RANK()를 사용한 쿼리도 RANK()를 사용한 쿼리와 구조는 동일하며, RANK() 대신 DENSE_RANK()를 사용한다는 점만 다릅니다. 대부분의 경우, 급여가 같은 사람을 모두 포함해야 한다는 요구사항에는 RANK()와 DENSE_RANK() 모두 동일하게 작동합니다.

어떤 함수를 선택해야 할까요?

  • RANK(): 만약 "급여 상위 3개 값"을 기준으로 하고 싶다면 RANK()를 사용하세요. 예를 들어, 1위, 2위, 3위, 3위, 5위 와 같이 순위가 건너뛸 수 있습니다.
  • DENSE_RANK(): 만약 "급여 상위 3개 순위"를 기준으로 하고 싶다면 DENSE_RANK()를 사용하세요. 예를 들어, 1위, 2위, 3위, 3위, 4위 와 같이 순위가 연속적입니다.

귀하의 요구사항인 "급여가 같은 사람이 여러 명이면 모두 포함해야 해요"라는 조건을 만족시키기 위해서는 두 함수 모두 효과적입니다. 일반적으로 이 경우 DENSE_RANK()가 좀 더 직관적일 수 있습니다.

DENSE_RANK 쿼리는 맞지만, RANK도 가능하다는 설명과 함수 선택 기준은 틀렸습니다.

  • 4 틀림
  • 0 의견 갈림
  • 4 문제없음
  • 2 누락

DeepSeek V4.1 Flash 및 Claude Haiku 4.5 검토 · 보고서 작성: GPT-5.6 Luna

틀린 부분

틀림 · 검토 모델 2개

이 요구사항에서는 두 함수 중 하나를 임의로 선택할 수 없습니다. 상위 3개의 서로 다른 급여 금액을 모두 포함하려면 DENSE_RANK()를 사용해야 하며, RANK()는 동점 때문에 일부 금액을 누락할 수 있습니다.

Gemini 2.5 Flash-Lite
다음은 employees 테이블에서 부서별로 급여 상위 3위 안에 드는 직원을 모두 포함하는 SQL 쿼리입니다. 급여가 같은 사람이 여러 명일 경우 모두 포함하도록 RANK() 또는 DENSE_RANK() 윈도우 함수를 사용합니다.
DeepSeek V4.1 Flash
“정답은 DENSE_RANK() <= 3이고 RANK() <= 3은 상위 급여에 3명 이상이 동점일 때 그 아래 금액을 받는 직원을 잘못 탈락시킨다.”
Claude Haiku 4.5
“이 경우 DENSE_RANK()를 사용해야 하며, RANK()는 적절하지 않습니다.”
틀림

두 함수는 동점이 순위에 영향을 주는 경우 결과가 달라집니다. 예를 들어 급여가 100, 100, 100, 90, 80이면 RANK() <= 3은 100만 반환하지만, 상위 3개 금액은 100·90·80이므로 전원을 포함해야 합니다.

Gemini 2.5 Flash-Lite
대부분의 경우, 급여가 같은 사람을 모두 포함해야 한다는 요구사항에는 RANK()와 DENSE_RANK() 모두 동일하게 작동합니다.
DeepSeek V4.1 Flash
“즉 두 함수는 동점이 있을 때 바로 그 지점에서 결과가 갈린다.”
틀림

이 함수 매핑은 뒤바뀌었습니다. ‘상위 3개 급여 값’은 DENSE_RANK() <= 3으로 구해야 하고, RANK()는 동점으로 순위가 건너뛰어 상위 3개 값 중 일부를 제외할 수 있습니다.

Gemini 2.5 Flash-Lite
RANK(): 만약 "급여 상위 3개 값"을 기준으로 하고 싶다면 RANK()를 사용하세요.
Claude Haiku 4.5
“"상위 3개의 서로 다른 급여 수준에 있는 모든 직원": DENSE_RANK() 사용”
틀림 · 검토 모델 2개

요구사항을 정확히 만족하는 것은 DENSE_RANK()입니다. RANK()는 동점자 자체는 함께 포함하지만, 그 동점으로 인해 뒤따르는 급여 순위가 4위 이상으로 밀리면 해당 급여를 누락합니다.

Gemini 2.5 Flash-Lite
귀하의 요구사항인 "급여가 같은 사람이 여러 명이면 모두 포함해야 해요"라는 조건을 만족시키기 위해서는 두 함수 모두 효과적입니다.
DeepSeek V4.1 Flash
“요구사항을 만족하는 것은 DENSE_RANK()뿐이다.”
Claude Haiku 4.5
“반면 RANK()는 순위를 건너뜁니다(1, 2, 2, 4). 따라서 3위에 사람이 많으면 4위는 제외되어, 사용자 요구사항을 만족하지 않을 수 있습니다.”

나머지

문제없는 부분4개 ▾
  • DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC)와 salary_rank <= 3을 사용하는 쿼리 구조는 정확합니다.
  • PARTITION BY department_id는 부서별로 순위를 계산하도록 합니다.
  • ORDER BY salary DESC는 각 부서에서 높은 급여부터 순위를 매기도록 합니다.
  • RANK()가 동점 뒤의 순위를 건너뛰고, DENSE_RANK()가 순위를 건너뛰지 않는다는 함수 정의는 정확합니다.
빠뜨린 부분2개 ▾
  • 요구사항의 ‘상위 3위’를 ‘상위 3개의 서로 다른 급여 금액’으로 해석해야 하며, 이 해석이 DENSE_RANK()를 선택하는 이유라는 설명이 명확하지 않았습니다.
  • ROW_NUMBER()를 사용하면 동점 직원 중 일부가 임의로 제외될 수 있다는 주의가 빠져 있습니다.
검토 모델 하나만 지적1개 ▾
  • DeepSeek V4.1 Flash: SQL Server의 TOP 3 WITH TIES도 이 요구사항에서는 동점으로 순위가 건너뛰는 경우를 해결하지 못할 수 있습니다. 확인 필요

수정한 답변

정답: DENSE_RANK() 사용

부서별로 서로 다른 급여 금액 상위 3개에 해당하는 직원을 동점자까지 모두 포함하려면 DENSE_RANK()를 사용합니다.

WITH RankedEmployees AS (
    SELECT
        id,
        name,
        department_id,
        salary,
        DENSE_RANK() OVER (
            PARTITION BY department_id
            ORDER BY salary DESC
        ) AS salary_rank
    FROM employees
)
SELECT
    id,
    name,
    department_id,
    salary
FROM RankedEmployees
WHERE salary_rank <= 3;

DENSE_RANK()는 같은 급여에 같은 순위를 부여하고 순위를 건너뛰지 않습니다. 따라서 급여가 100, 100, 100, 90, 80이라면 순위는 1, 1, 1, 2, 3이 되어 다섯 명 모두 반환됩니다.

반면 RANK()는 같은 급여 뒤의 순위를 건너뜁니다. 같은 데이터에서 순위가 1, 1, 1, 4, 5가 되므로 RANK() <= 3을 사용하면 100을 받는 직원만 반환되어 90과 80을 놓칠 수 있습니다.

따라서 이 요구사항에는 DENSE_RANK() <= 3이 적절하며, ROW_NUMBER()는 동점 직원을 일부 제외할 수 있으므로 사용하지 않는 것이 좋습니다.

편집팀 확인

공개 전에 이 보고서를 읽고 확인했습니다

SQLite에서 급여 100, 100, 100, 90, 80으로 실행해 봤습니다. DENSE_RANK() <= 3은 다섯 명을 모두, RANK() <= 3은 100을 받는 세 명만 돌려줍니다. 보고서의 설명과 같습니다.

2026년 10월 28일에 아래 자료와 대조해 확인했습니다.

출처:

검토 모델별 전체 의견

DeepSeek V4.1 Flash▾

1. 내 답변

질문의 "부서별로 급여 상위 3위 안에 드는 금액을 받는 직원을 모두" + "동점자는 전원 포함"은 "부서별 상위 3개 급여 값에 해당하는 직원 전원"을 뜻하므로, 정답은 DENSE_RANK() <= 3이고 RANK() <= 3은 상위 급여에 3명 이상이 동점일 때 그 아래 금액을 받는 직원을 잘못 탈락시킨다. 따라서 검토 대상 답변의 DENSE_RANK 쿼리 자체는 맞지만, "두 함수 모두 이 요구사항에 효과적"이라는 결론과 함수별 설명 매핑은 틀렸다.

2. 주장별 검토

DENSE_RANK 쿼리 (정답 부분) — holds. DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) + WHERE salary_rank <= 3은 요구사항을 정확히 만족한다. 구조 설명도 정확하다.

"두 함수 모두 동일하게 작동" — wrong.

"대부분의 경우, 급여가 같은 사람을 모두 포함해야 한다는 요구사항에는 RANK()와 DENSE_RANK() 모두 동일하게 작동합니다."

반례(한 부서 급여 100, 100, 100, 90, 80):

salary RANK DENSE_RANK
100 1 1
100 1 1
100 1 1
90 4 2
80 5 3

상위 3개 급여 값은 {100, 90, 80}이므로 5명 전원이 포함되어야 하는데, RANK() <= 3은 100을 받는 3명만 남기고 90·80을 탈락시킨다. 즉 두 함수는 동점이 있을 때 바로 그 지점에서 결과가 갈린다.

"두 함수 모두 효과적"이라는 결론 — wrong.

"귀하의 요구사항인 "급여가 같은 사람이 여러 명이면 모두 포함해야 해요"라는 조건을 만족시키기 위해서는 두 함수 모두 효과적입니다."

요구사항을 만족하는 것은 DENSE_RANK()뿐이다.

"어떤 함수를 선택해야 할까요?" 항목의 함수 매핑 — wrong(뒤바뀜).

"RANK(): 만약 "급여 상위 3개 값"을 기준으로 하고 싶다면 RANK()를 사용하세요."

"상위 3개 값(금액)"은 DENSE_RANK()의 의미다. RANK()는 "상위 3개 순위 자리"에 가깝고, 동점이 상위에 몰리면 3개 값보다 적게 반환한다. 같은 이유로 두 번째 항목의 "상위 3개 순위 → DENSE_RANK" 대응도 서술이 뒤집혀 있다(두 항목에 든 순위 예시 1,2,3,3,5 / 1,2,3,3,4 자체는 각각 RANK·DENSE_RANK의 정의로 맞다).

"DENSE_RANK가 좀 더 직관적일 수 있습니다" — wrong(문제를 흐림).

"일반적으로 이 경우 DENSE_RANK()가 좀 더 직관적일 수 있습니다."

취향/직관의 문제가 아니라, RANK는 요구사항을 위반한다. 선택 기준을 "직관"이라고 표현하면 독자가 RANK를 써도 된다고 오해한다.

서두의 "RANK() 또는 DENSE_RANK()" 표현 — wrong. "또는"이 둘 다 가능하다는 인상을 준다.

참인 부분: RANK()가 동점 시 다음 순위를 건너뛴다는 정의, "동점이 3위 자리에 있으면 전원 포함된다"는 문장("같은 급여를 받는 여러 명의 직원이 3위 안에 포함될 수 있습니다" — 사실이나 일반적 보장으로 읽히면 오해 소지), DENSE_RANK()가 순위를 건너뛰지 않는다는 설명, 두 쿼리가 함수명만 다르다는 설명은 모두 정확하다.

3. 빠뜨린 내용

  • 요구사항 ↔ 함수 대응의 명시: "급여 상위 3위 안에 드는 금액" = "상위 3개 서로 다른 급여 값" → DENSE_RANK. 이 한 줄이 답변의 핵심인데 빠져 있다.
  • 왜 RANK가 부족한지의 조건: 상위 급여에 3명 이상 동점자가 있을 때(즉 3번째 값보다 위쪽에서 순위가 벌어질 때)만 결과가 달라진다. 두 함수가 같은 결과를 내는 경우(예: 100, 90, 80, 80, 70)와 다른 경우를 나눠 주면 오해가 없다.
  • ROW_NUMBER() 금지 언급: 동점자 처리를 위해 흔히 ROW_NUMBER()를 쓰면 임의로 한 명만 남아 요구사항 위반이라는 경고가 있으면 좋다.
  • SQL Server TOP 3 WITH TIES 주의: 이 옵션도 마지막 행과의 동점만 포함하는 RANK식 의미라, 위 반례에서 90·80을 놓친다. 다른 방식을 제안할 때 필요한 주의점이다.
  • 윈도우 함수 미지원 환경 대안: MySQL 5.7 등에서는 상관 서브쿼리(WHERE salary >= (SELECT ... ORDER BY salary DESC LIMIT 1 OFFSET 2) 형태의 3번째 값)나 조인으로 대체해야 한다.
  • 사소한 것: salary가 NULL인 경우(정렬에서 전부 최하위)와 (department_id, salary) 인덱스 성능 언급. 부서 인원이 3명 미만이면 자동으로 전원 포함된다는 점도 굳이 필요하진 않다.

4. 수정된 답변

나머지 부분(쿼리 구조, DENSE_RANK 설명, 두 쿼리 비교)은 그대로 두고, 잘못된 결론과 매핑만 다음과 같이 고친다.

1. DENSE_RANK() 함수를 사용한 방법 (권장)

요구사항은 "부서별로 급여가 상위 3개 값에 속하는 직원을 전원 포함"이므로, 동점자에게 같은 순위를 주고 순위를 건너뛰지 않는 DENSE_RANK()를 사용해야 한다.

WITH RankedEmployees AS (
    SELECT id, name, department_id, salary,
           DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_rank
    FROM employees
)
SELECT id, name, department_id, salary
FROM RankedEmployees
WHERE salary_rank <= 3;
2. RANK()는 이 요구사항에 부적합

RANK()는 동점 뒤의 순위를 건너뛰므로, 상위 급여에 동점자가 3명 이상이면 상위 3개 금액에 속하는데도 탈락하는 직원이 생긴다. 예: 한 부서 급여가 100, 100, 100, 90, 80이면 RANK()는 1, 1, 1, 4, 5를 부여해 90·80을 제외하지만, 상위 3개 금액은 {100, 90, 80}이므로 5명 모두 포함되어야 한다(DENSE_RANK()는 1, 1, 1, 2, 3을 부여).

정리
  • "동점자는 전원 포함"만이 아니라 "상위 3개 금액" 기준이므로 DENSE_RANK() <= 3이 정답이다.
  • 동점자가 3위 자리(또는 상위 아무 자리)에 있어도 DENSE_RANK()는 모두 포함한다.
  • ROW_NUMBER()나 SQL Server의 TOP 3 WITH TIES는 이 요구사항을 만족하지 못하므로 사용하지 않는다.
Claude Haiku 4.5▾

리뷰

나의 답변

사용자의 요구사항 "부서별로 급여 상위 3위 안에 드는 금액을 받는 직원을 모두 포함"은 동일한 급여를 받는 모든 직원을 포함하는 것을 의미합니다. 이 경우 DENSE_RANK()를 사용해야 하며, RANK()는 적절하지 않습니다.

주요 오류

RANK() 함수의 설명이 잘못되었습니다.

답변에서:

"만약 '급여 상위 3개 값'을 기준으로 하고 싶다면 RANK()를 사용하세요. 예를 들어, 1위, 2위, 3위, 3위, 5위 와 같이 순위가 건너뛸 수 있습니다."

이것은 오류입니다. RANK()를 사용하여 WHERE salary_rank <= 3로 필터링하면, 1위, 2위, 3위 순위만 반환되고, 5위는 포함되지 않습니다.

실제 동작:

  • RANK()로 <= 3을 필터링하면: 1위, 2위, 2위 직원만 반환 (정확히 3개 순위 위치에만 해당)
  • DENSE_RANK()로 <= 3을 필터링하면: 1위, 2위, 2위, 3위 직원 반환 (3개의 서로 다른 급여 수준 모두 포함)

datadank.com의 비교표에 따르면, 2위에 두 명이 같은 급여로 있을 때:

  • RANK() <= 3: Ana(120), Bo(110), Cy(110)만 반환
  • DENSE_RANK() <= 3: Ana(120), Bo(110), Cy(110), Di(100) 반환

빠뜨린 내용

RANK() vs DENSE_RANK() 선택 기준이 부정확합니다.

답변에서 두 함수 모두 사용자의 요구사항을 만족한다고 했으나, aryasoft.com과 datadank.com의 자료에 따르면:

  • "상위 3개의 서로 다른 급여 수준에 있는 모든 직원": DENSE_RANK() 사용
  • "상위 3개 순위 위치에 있는 직원": RANK() 사용

사용자 요구사항 "급여 상위 3위 안에 드는 금액을 받는 직원을 모두 포함"은 전자를 의미하므로, DENSE_RANK()가 정답입니다.

수정된 답변

두 함수를 모두 제시하는 것은 좋으나, 다음과 같이 명확히 해야 합니다:

올바른 답변 (DENSE_RANK 사용 권장)

귀하의 요구사항 "급여가 같은 사람이 여러 명이면 모두 포함해야 해요"를 정확히 만족시키려면 DENSE_RANK()를 사용해야 합니다.

WITH RankedEmployees AS (
    SELECT
        id,
        name,
        department_id,
        salary,
        DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) as salary_rank
    FROM
        employees
)
SELECT
    id,
    name,
    department_id,
    salary
FROM
    RankedEmployees
WHERE
    salary_rank <= 3;

왜 DENSE_RANK()인가?

DENSE_RANK()는 동일한 급여에 동일한 순위를 부여하면서도, 다음 순위를 건너뛰지 않습니다(1, 2, 2, 3). 따라서 WHERE salary_rank <= 3으로 필터링할 때 상위 3개의 서로 다른 급여 수준 모두를 포함합니다.

반면 RANK()는 순위를 건너뜁니다(1, 2, 2, 4). 따라서 3위에 사람이 많으면 4위는 제외되어, 사용자 요구사항을 만족하지 않을 수 있습니다.

RANK() 사용 시 주의

RANK()를 사용하면, 2위에 여러 명이 있을 경우 3위 이상의 직원들이 제외될 수 있습니다. 이는 "상위 3위 안에 드는 모든 직원 포함"이라는 요구사항에 맞지 않습니다.

참고한 페이지: LeetCode SQL Problem & Solution: Department Top Three Salaries | LearnSQL.com · Top N per Group in SQL: Top 3 Salaries per Dept | DataDank · Top N per Group in SQL Server: 3 Methods Compared · How to Find the Nth-Highest Salary by Department with SQL | LearnSQL.com · 43-00185-department-top-three-salaries.sql

이제 직접 해 보세요

그 답변을 믿기 전에, 먼저 검토하세요.

ChatGPT, Claude, Gemini 등 어떤 AI의 답변이든 붙여 넣으세요. 다른 회사의 AI 두 곳이 살펴보고 틀린 곳을 알려 줍니다.

답변 검토하기 Chrome 확장 프로그램 추가

ChatGPT, Claude, Gemini의 모든 답변 아래에 검토 버튼이 생깁니다.

다른 검토 예시