| # | 문제 | 난이도 | 핵심 개념 |
|---|---|---|---|
| 175 | Combine Two Tables | Easy | LEFT JOIN |
| 176 | Second Highest Salary | Medium | DENSE_RANK, NULL 반환 |
| 181 | Employees Earning More Than Their Managers | Easy | Self Join |
| 584 | Find Customer Referee | Easy | NULL 비교 연산 |
| 1978 | Employees Whose Manager Left the Company | Easy | NOT IN + 서브쿼리 |
Person 테이블의 모든 사람에 대해 이름과 주소를 반환한다. Address 테이블에 주소가 없으면 NULL을 반환한다.
| JOIN 종류 | 결과 |
|---|---|
INNER JOIN | 양쪽 테이블 모두에 매칭되는 행만 반환 |
LEFT JOIN | 왼쪽 테이블은 전부 반환, 오른쪽에 없으면 NULL |
RIGHT JOIN | 오른쪽 테이블은 전부 반환, 왼쪽에 없으면 NULL |
SELECT p.firstName, p.lastName, a.city, a.state
FROM Person p
LEFT JOIN Address a ON p.personId = a.personId
Employee 테이블에서 두 번째로 높은 distinct salary를 반환한다. 없으면 NULL 반환.
| salary | RANK() | DENSE_RANK() |
|---|---|---|
| 300 | 1 | 1 |
| 300 | 1 | 1 |
| 200 | 3 | 2 |
SELECT MAX(salary) AS SecondHighestSalary
FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM Employee
) ranked
WHERE rnk = 2
자신의 매니저보다 급여가 높은 직원의 이름을 반환한다.
같은 테이블을 두 개인 것처럼 alias를 다르게 줘서 JOIN하는 기법.
SELECT e.name AS Employee
FROM Employee e
JOIN Employee m ON e.managerId = m.id
WHERE e.salary > m.salary
referee_id가 2가 아니거나, 추천인이 없는(NULL) 고객의 이름을 반환한다.
NULL과의 모든 비교 연산은 TRUE/FALSE가 아닌 NULL(unknown)을 반환한다.
SELECT name
FROM Customer
WHERE referee_id != 2 OR referee_id IS NULL
급여가 $30,000 미만이면서 매니저가 회사를 떠난 직원의 ID를 반환한다.
| manager_id | 의미 |
|---|---|
| NULL | 처음부터 매니저 없음 (최상위 직원) |
| 존재하지 않는 ID | 매니저가 퇴사함 ← 우리가 찾는 경우 |
SELECT employee_id
FROM Employees
WHERE salary < 30000
AND manager_id IS NOT NULL
AND manager_id NOT IN (SELECT employee_id FROM Employees)
ORDER BY employee_id
| 개념 | 한 줄 요약 |
|---|---|
| LEFT JOIN | 기준 테이블의 모든 행 보존, 매칭 없으면 NULL |
| Self Join | 같은 테이블을 두 번 사용해 계층 관계 비교 |
| DENSE_RANK | 동점자가 있어도 순위를 연속으로 매김 |
| NULL 비교 | = NULL ❌ → IS NULL ✅ |
| NOT IN | IS NOT IN ❌ → NOT IN ✅, NULL 포함 시 주의 |