https://school.programmers.co.kr/learn/courses/30/lessons/276013
DEVELOPER_INFOS 테이블은 개발자들의 프로그래밍 스킬 정보를 담은 테이블입니다. DEVELOPER_INFOS 테이블 구조는 다음과 같으며, ID, FIRST_NAME, LAST_NAME, EMAIL, SKILL_1, SKILL_2, SKILL_3는 각각 ID, 이름, 성, 이메일, 첫 번째 스킬, 두 번째 스킬, 세 번째 스킬을 의미합니다.
| NAME | TYPE | UNIQUE | NULLABLE |
|---|---|---|---|
| ID | VARCHAR(N) | Y | N |
| FIRST_NAME | VARCHAR(N) | N | Y |
| LAST_NAME | VARCHAR(N) | N | Y |
| VARCHAR(N) | Y | N | |
| SKILL_1 | VARCHAR(N) | N | Y |
| SKILL_2 | VARCHAR(N) | N | Y |
| SKILL_3 | VARCHAR(N) | N | Y |
DEVELOPER_INFOS 테이블에서 Python 스킬을 가진 개발자의 정보를 조회하려 합니다. Python 스킬을 가진 개발자의 ID, 이메일, 이름, 성을 조회하는 SQL 문을 작성해 주세요.
결과는 ID를 기준으로 오름차순 정렬해 주세요.
예를 들어 DEVELOPER_INFOS 테이블이 다음과 같다면
| ID | FIRST_NAME | LAST_NAME | SKILL_1 | SKILL_2 | SKILL_3 | |
|---|---|---|---|---|---|---|
| D165 | Jerami | Edwards | jerami_edwards@grepp.co | Java | JavaScript | Python |
| D161 | Carsen | Garza | carsen_garza@grepp.co | React | ||
| D164 | Kelly | Grant | kelly_grant@grepp.co | C# | ||
| D163 | Luka | Cory | luka_cory@grepp.co | Node.js | ||
| D162 | Cade | Cunningham | cade_cunningham@grepp.co | Vue | C++ | Python |
다음과 같이 Python 스킬을 가진 개발자의 정보가 결과에 나와야 합니다.
| ID | FIRST_NAME | LAST_NAME | |
|---|---|---|---|
| D162 | cade_cunningham@grepp.co | Cade | Cunningham |
| D165 | jerami_edwards@grepp.co | Jerami | Edwards |
문제 풀이 방법이 너무 다양하지만 가장 효율적인 방법은 무엇일지 고민해 보아야 한다.
| 방식 | 예시 쿼리 | 특징 |
|---|---|---|
| ① OR 조건 | sql SELECT ID, EMAIL, FIRST_NAME, LAST_NAME FROM DEVELOPER_INFOS WHERE SKILL_1 = 'Python' OR SKILL_2 = 'Python' OR SKILL_3 = 'Python' ORDER BY ID; | ✅ 가장 일반적이고 효율적 각 컬럼이 인덱스 되어 있다면 인덱스 병합(Index Merge)으로 처리 가능 |
| ② IN 조건 (비권장) | sql WHERE 'Python' IN (SKILL_1, SKILL_2, SKILL_3) | 🚫 MySQL 등에서는 성능상 OR와 동일하거나 더 느림 |
| ③ UNION ALL | sql SELECT ID, EMAIL, FIRST_NAME, LAST_NAME FROM DEVELOPER_INFOS WHERE SKILL_1 = 'Python' UNION ALL SELECT ... (SKILL_2)... UNION ALL SELECT ... (SKILL_3)... ORDER BY ID; | 🚫 중복 제거 없이 3번 풀스캔함. 효율 낮음. |
| ④ UNPIVOT (테이블 구조 변환) | sql SELECT ID, EMAIL, FIRST_NAME, LAST_NAME FROM (SELECT ID, EMAIL, FIRST_NAME, LAST_NAME, SKILL FROM DEVELOPER_INFOS UNPIVOT (SKILL FOR SKILL_COL IN (SKILL_1, SKILL_2, SKILL_3))) AS U WHERE SKILL = 'Python' ORDER BY ID; | ✅ 구조적으로 깔끔하지만, UNPIVOT 지원 안 하는 DB(MySQL)에서는 불가. |
| ⑤ JSON / ARRAY 구조 활용 | sql WHERE JSON_CONTAINS(JSON_ARRAY(SKILL_1, SKILL_2, SKILL_3), '"Python"') | ✅ 스키마가 JSON 기반이라면 효율적 🚫 일반 문자열 컬럼에서는 오히려 느림 |
| 방법 | 쿼리 속도 (대략적) | 인덱스 사용 | 주로 쓰이는 환경 |
|---|---|---|---|
| OR 조건 | 🔹빠름 | ✅ 가능 | ✅ 일반 RDBMS에서 표준 |
| IN 조건 | 🔸보통 | ❌ 거의 안 됨 | 단순한 경우만 |
| UNION ALL | 🔸보통~느림 | ❌ | 스키마 변환 테스트용 |
| UNPIVOT | 🔸보통 | ❌ | Oracle, SQL Server 등에서 구조적 쿼리 작성용 |
| JSON_CONTAINS | 🔹빠름 (JSON 인덱스 있을 때만) | ✅ | JSON 스키마 기반 DB |
가장 효율적인 방법
SELECT
ID,
EMAIL,
FIRST_NAME,
LAST_NAME
FROM DEVELOPER_INFOS
WHERE
SKILL_1 = 'Python'
OR SKILL_2 = 'Python'
OR SKILL_3 = 'Python'
ORDER BY ID;