๐ ๋ณธ ํฌ์คํ ์์ ์ฌ์ฉ๋๋ ํ ์ด๋ธ์ ์๋ฃ์ ์ถ์ฒ๋ Leetcode์์ ๋ฐํ๋๋ค. ๋ ๋ค์ํ SQL ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์๋ ค๋ฉด Leetcode ์ฌ์ดํธ๋ฅผ ๋ฐฉ๋ฌธํด ๋ณด์ธ์!
์ด๋ฒ ํฌ์คํ ์์๋ SQL๋ Python๊ณผ ๊ฐ์ ๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ค์ฒ๋ผ ์ฌ์ฉ์ ํจ์๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๊ณ ์ด๋ฅผ ์ด์ฉํด ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๋ ค ํ๋ค. ์ฌ๊ธฐ์๋ MySQL ๊ธฐ์ค์ผ๋ก์ ์ฌ์ฉ์ ํจ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ํด์๋ง ์๊ฐํ๋ค. ์ฐ์ MySQL๋ก ์ฌ์ฉ์ ํจ์๋ฅผ ๋ง๋๋ ๊ตฌ์กฐ์ ๋ํด์ ์์๋ณด์.
์์ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋จํ ์ค๋ช ํ๋ฉด CREATE FUNCTION~ ์ฒซ ๋ฒ์งธ RETURNS ๋ถ๋ถ์ ์ธํ ๋ณ์์ ์์ํ์ผ๋ก ๋ด๋ฑ์ ๊ฐ์ type์ ์ ํ๋ ๋ถ๋ถ์ด๋ฉฐ BEGIN ~ END ์ฌ์ด์๋ ์ถ๋ ฅ๊ฐ์ ๋ด๋ฑ๊ธฐ ์ํ ์ฐ์ฐ๊ณผ ๋ณ์๋ฅผ ํ ๋นํ๋ ๋ถ๋ถ์ด๋ผ ํ ์ ์๋ค. ๊ตฌํํด์ผ ํ ๋ ์ฃผ์ํด์ผ ํ ์ ์ ๋ ๊ฐ์ง์ด๋ค.(ํ์๊ฐ ์์ฃผํ๋ ์ค์๋ค..)
- ์ฒซ ๋ฒ์งธ๋ RETURNS ์ด๊ณ ๋ ๋ฒ์งธ๋ RETURN ์ด๋ค! S์ ์ ๋ฌด๋ฅผ ์ฃผ์ํ์.
- ๋ค๋ฅธ ๋ถ๋ถ์๋ ์ธ๋ฏธ์ฝ๋ก (;)์ ์ ๋ถ์ฌ๋ ๋์ง๋ง ๋นจ๊ฐ์์ผ๋ก ํ๊ธฐ๋ ๋ถ๋ถ(๋ณ์๋ฅผ ํ ๋นํ๊ณ ์ฟผ๋ฆฌ๋ก ์์ํ์ return ํ๋ ๋ถ๋ถ)์ ๋ฌด์กฐ๊ฑด ์ธ๋ฏธ์ฝ๋ก (;)์ ์ ์ด์ฃผ์ด์ผ ํ๋ค.
์, ์ด์ Leetcode์ 177๋ฒ ๋ฌธ์ ๋ฅผ ์ฌ์ฉ์ ํจ์๋ฅผ ์ ์ํด์ ํ์ดํด๋ณด์. ์ฐ์ ๋ฌธ์ ์ ์ํ๋ ํํ์ ์ถ๋ ฅ ํฌ๋งท์ ํ์ธํด๋ณด์.
Write a SQL query to get the nth highest salary from the Employee table.
(Employee ํ ์ด๋ธ์์ n๋ฒ์งธ๋ก ๊ฐ์ฅ ๋ง์ salary๋ฅผ ์ถ๋ ฅํด๋ผ. ์ด ๋ ๋ง์ฝ n๋ฒ์งธ ๊ฐ์ฅ ๋ง์ salary๊ฐ์ด ์๋ค๋ฉด null๊ฐ์ ์ถ๋ ฅ์์ผ๋ผ.)
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ํฐ ํ์ ์ฌ์ฉ์ ์ ์ ํจ์๋ฅผ ์ฌ์ฉํด์ ํ์ดํ์ง๋ง ํจ์ ๋ด๋ถ์ ์ผ๋ก ํ์ด๋ฐฉ๋ฒ์ด 3๊ฐ์ง๊ฐ ์๋ค. ์ด๋ฅผ ํ๋์ฉ ์๊ฐํด๋ณธ๋ค.
1. LIMIT ๊ณผ OFFSET ํ์ฉํ๊ธฐ
์ฐ์ LIMIT๊ณผ OFFSET์ ๋ํ ๊ฐ๋ ์ ๋ชจ๋ฅธ๋ค๋ฉด ์ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ์. ์ด ํฌ์คํ ์์๋ ์์ ์ฟผ๋ฆฌ๋ฌธ ํ๋๋ก ๊ฐ๋จํ๊ฒ ๊ฐ๋ ์ ์ง๊ณ ๋์ด๊ฐ์.
SELECT Salary FROM Employee ORDER BY Salary DESC LIMIT 2, 3
์ ์ฟผ๋ฆฌ๋ฅผ ํด์ํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค. Employee ํ ์ด๋ธ์์ Salary๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํ ํ ์์ 2๋ฒ์งธ ์ดํ์ ์์ 3๊ฐ ๊ฐ. ๋ง์ฝ [1, 2, 3, 4, 5, 6, ..] ์์๋ก ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด ์ ์ฟผ๋ฆฌ๋ 3, 4, 5 ๋ฒ์งธ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅ์ํจ๋ค.
SELECT Salary FROM Employee ORDER BY Salary DESC LIMIT 3 OFFSET 2
์ด ์ฟผ๋ฆฌ๋ OFFSET๊ณผ LIMIT์ ๊ฒฐํฉํ์ฌ ์์ ์ฟผ๋ฆฌ์ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅ์ํจ๋ค. ์ถ๊ฐ๋ก OFFSET์ ์ธ์๋ก ํฐ ์ซ์๋ฅผ ๋ฃ์์๋ก ์ฟผ๋ฆฌ ํผํฌ๋จผ์ค๊ฐ ๋จ์ด์ง๋ค๋ ์ ์ ์ฐธ๊ณ ํ์. ์๋ฅผ ๋ค์ด ์์ 100๋ฒ์งธ ์ดํ์ ์์ 3๊ฐ์ ๊ฐ์ ์ถ์ถํ๋ ค ํ๋ค๋ฉด
LIMIT 3 OFFSET 100 ์ด ์๋ LIMIT 100, 3์ ์ฌ์ฉํ๋๋ก ํ์.
์ด์ LIMIT๊ณผ OFFSET์ ํ์ฉํด 177๋ฒ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์.
CREATE FUNCTION getNthHighestSalary (N INT)
RETURNS INT
BEGIN
DECLARE A INT;
SET A = N-1;
RETURN (SELECT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET A);
END
์ฌ๊ธฐ์ ์๋ฌธ์ด ๋ค ์ ์๋ ๋ถ๋ถ์ ์ ๊ตณ์ด A๋ฅผ N-1๋ก ์๋ก์ด ๋ณ์๋ฅผ ํ ๋นํ๋๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์ด๋ ๊ฒ ํ ์ด์ ๋ ์ฌ์ฉ์ํจ์์ ์ธํ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๊ณ ์๋ N์ ํจ์ ๋ด๋ถ์์ ์๋ก์ด ๋ณ์๋ฅผ ํ ๋นํ์ง ์๊ณ N-1 ๊ทธ๋๋ก ์ฌ์ฉํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฆฌ๊ณ N๋ฒ์งธ ์์์ ๊ฐ์ด ์๋ค๋ฉด Null์ ๋ฐํํ๋ผ๊ณ ํ๋๋ฐ, LIMIT ๊ณผ OFFSET์ ํด๋น ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๊ฐ์ด ์๋ค๋ฉด ์๋์ผ๋ก Null์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ์ํด ๋ฐ๋ก ์ฒ๋ฆฌํด์ค ํ์๋ ์๋ค.
2. CASE WHEN๊ณผ ์๋ธ์ฟผ๋ฆฌ ์ฌ์ฉํ๊ธฐ
CASE WHEN์ ์ฌ์ฉํด๋ณผ ์ ๋ ์๋ค. ๋ค์ SQL ๊ตฌ๋ฌธ์ ๋ณด์.
CREATE FUNCTION getNthHighestSalary (N INT)
RETURNS INT
BEGIN
RETURN (SELECT CASE WHEN COUNT(sub.Salary) < N
THEN Null
ELSE MIN(sub.Salary)
END
FROM (SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT N) sub);
END
3. IF์ ์๋ธ์ฟผ๋ฆฌ ์ฌ์ฉํ๊ธฐ
2๋ฒ ํ์ด๋ฐฉ๋ฒ์์ CASE WHEN ๊ตฌ๋ฌธ์ IF ๊ตฌ๋ฌธ์ผ๋ก ๋ฐ๊พธ์ด ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
CREATE FUNCTION getNthHighestSalary (N INT)
RETURNS INT
BEGIN
RETURN (SELECT IF(COUNT(sub.Salary) < N, Null, MIN(sub.Salary))
FROM (SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT N) sub);
END
์ด์ ๋ชจ๋ ํ์ด๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ง์ ์ ์ํด์ค ํจ์๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ ๊น? ์๋์ ๊ฐ์ด ์ฌ์ฉํ๋ฉด ๋๋ค.(ํด๋น ๋ฆฌํธ์ฝ๋ ๋ฌธ์ ์์๋ ํจ์ ์ฟผ๋ฆฌ๋ฌธ๋ง ์ ์ถํ๋ฉด ํต๊ณผ๋๋ค)
-- ์์ 10๋ฒ์งธ๋ก ๋์ Salary๋ฅผ ์ถ๋ ฅํ๊ธฐ!
SELECT getNthHighestSalary(10)
FROM Employee