Day to_day

[MySQL] 결과 값 제한하기 - LIMIT 활용하기 본문

SQL

[MySQL] 결과 값 제한하기 - LIMIT 활용하기

m_inglet 2023. 2. 7. 01:04
728x90
반응형

포스팅 개요

SQL의 LIMIT 기본 문법을 정리하고, 리트코드 문제로 LIMIT 구문을 응용해 보기 위해서 포스팅을 작성한다.

 

 

기본 문법

LIMIT는 결과에서 몇 개의 행을 반환할 것인지 제한하는 구문이다.

두 가지의 방법으로 LIMIT를 활용 할 수 있다.

LIMIT 구문은 SELECT 명령의 마지막에 지정하는 것으로 WHERE이나 ORDER BY 구문의 뒤에 위치한다.

SELECT 컬럼명
FROM 테이블명
LIMIT 개수;

SELECT 컬럼명
FROM 테이블명
LIMIT 개수 OFFSET 시작 인덱스;

 

 

1. LIMIT 개수

이때 LIMIT 뒤에 숫자가 인덱스가 아닌 개수를 의미하는 것을 유의해야 한다.

SELECT *
FROM BOOK
LIMIT 1;

< 실행 결과 >

맨 위에 있는 행 한 개만 추출된다.

 

 

 

2. LIMIT OFFSET, 개수

여기서 유의할 점은 LIMIT 뒤엔 출력 개수가 들어가고, OFFSET 뒤엔 시작 인덱스가 들어간다.

OFFSET은 0부터 시작하므로 0,1,2,3 결국 네 번째 행에 해당하는 값이 반환된다.

SELECT *
FROM BOOK
LIMIT 1 OFFSET 3;

< 실행 결과 >

 

 

3. OFFSET 생략 

비슷한데 OFFSET을 생략하고 사용할 수도 있다.

아래의 경우는 위의 코드와 비슷해 보이지만 완전히 다른 값을 반환한다.

'LIMIT 시작 인덱스, 개수'의 형태로 들어가서 1번 인덱스부터 3개의 행을 반환한 결과가 된다.

SELECT *
FROM BOOK
LIMIT 1, 3;

< 실행 결과 >

 

 

 

리트코드 문제로 LIMIT 응용하기

문제 : 176. Second Highest Salary

 

[지시 사항]

Write an SQL query to report the second highest salary from the Employee table.

If there is no second highest salary, the query should report null.

 

[해석]

Employee 테이블에서 두 번째로 높은 salary를 구하시오. 만약 두번째로 높은 salary가 없다면 null 값을 반환하라.

 

[내가 작성한 코드]

WITH PIVOT AS (SELECT salary
    FROM Employee
    ORDER BY salary DESC
    LIMIT 1,1)

SELECT
    IFNULL(MAX(p.salary), null) AS SecondHighestSalary
FROM PIVOT p;

 

[코드 해설]

지시사항의 첫 번째 문장의 경우 다음의 코드로 해결할 수 있었다.

SELECT salary AS SecondHighestSalary
FROM Employee
ORDER BY salary DESC
LIMIT 1, 1;

LIMIT을 사용해서 인덱스 1부터 한 개의 행만 추출하는 것이다.

하지만 이 경우 두 번째로 높은 salary가 존재하지 않을 때 null을 반환해 주는 조건이 포함되어있지 않다.

 

그래서 with 절을 이용해 위의 코드를 새로 테이블로 만들었다.

 

그리고 다음 select절만 뽑아서 살펴보자면,

SELECT
    IFNULL(MAX(p.salary), null) AS SecondHighestSalary
FROM PIVOT p;

참고로 IFNULL(칼럼명, NULL인 경우 대체할 값) 이렇게 쓸 수 있다.

 

하지만 주의할 점은 아래와 같이 쓰면 p.salary 값이 아예 없는 경우엔 적용이 안된다. null인 경우 대체값으로 넣기 위해선 값이 없는 p.salary에 null 값을 넣어줘야 한다.

IFNULL((p.salary), null)

 

이럴 경우엔 집계함수를 넣어서 null 값을 뱉어내게 해야 한다.

아래와 같이 하면 p.salary의 최댓값은 없기 때문에 null 값을 반환한다. 

IFNULL(MAX(p.salary), null)

 

하지만 위의 코드로 작성할 경우 반례가 존재한다. 1등이 동률로 2명이 존재하고, 2등이 없는 경우 값을 반환하지 못한다. 

이 때문에 dense_rank 또는 rank를 이용하여 문제를 해결해 주어야 한다. 

오늘은 LIMIT 구문을 응용해 보기 위해 코드를 작성해 본 것이고, 혹시 궁금하신 분들을 위해서 정답 코드를 남겨두겠다.

 

 

[정답 코드]

with pivot as (select salary, (dense_rank() over (order by salary desc))as ranking
    from Employee)

select 
    (case when max(p.salary) then p.salary else null end) as SecondHighestSalary
from pivot p
where p.ranking = 2;
728x90
반응형
Comments