📑 1. 문제설명
https://school.programmers.co.kr/learn/courses/30/lessons/276035
문제요약
- SKILLCODES 테이블
- 스킬 정보 (이름, 범주, 코드) 저장
- CODE는 2진수 비트마스크 표현 가능 (2의 제곱수)
- DEVELOPERS 테이블
- 개발자 정보 (ID, 이름, 성, 이메일, 스킬코드) 저장
- SKILL_CODE는 여러 스킬을 비트 OR 연산으로 합쳐 놓은 값
- 조건
- Front End 스킬을 가진 개발자를 찾기
- DEVELOPERS.SKILL_CODE와 SKILLCODES.CODE를 비트 AND 연산해서 0보다 크면 Front End 스킬 보유자임
- 중복 제거 필요 (같은 개발자가 여러 Front End 스킬을 가지고 있을 수 있음)
- 출력 컬럼
- ID, EMAIL, FIRST_NAME, LAST_NAME
- 정렬 기준
- ID 오름차순
❌ 2. 실패한 시도
이건 이진법 비트연산 문제라 복잡하게 생각하면 어렵다
WITH FRONT_SKILLS AS (
SELECT CODE
FROM SKILLCODES
WHERE CATEGORY = 'Front End'
)
SELECT ID, EMAIL, FIRST_NAME, LAST_NAME
FROM DEVELOPERS
JOIN FRONT_SKILLS ON SKILL_CODE & CODE
ORDER BY ID;
이문제는 SKILL_CODE가 비트마스크 형태로 여러 기술을 담고 있는 구조이다. 먼저, SKILLCODES 테이블에서 카테고리가 FRONTEND인 CODE인 데이터만 CTE로 추출한 다음, DEVELOPERS 테이블과 비트연산(AND) 조인해서 해결했다.
틀린 이유
SELECT 절에 DISTINCT 안 붙여서 틀렸다.
- WITH FRONT_SKILLS 안에서 CATEGORY = 'Front End' 조건으로 여러 개의 CODE가 나올 수 있다. 예를 들어 Front End 기술이 HTML, CSS, JS, React 라고 치면 → CODE는 4개이다.
- DEVELOPERS 테이블에서 한 명의 개발자가 SKILL_CODE에 여러 개의 Front End 기술을 가지고 있으므로 FRONT_SKILLS의 여러 행과 매칭되서 1인 : FRONT_SKILLS N개와 JOIN되는 결과가 발생한다. 그래서 같은 개발자가 여러 줄로 출력된다.
⭐ 3. 정답코드
WITH FRONT_SKILLS AS (
SELECT CODE
FROM SKILLCODES
WHERE CATEGORY = 'Front End'
)
SELECT DISTINCT ID, EMAIL, FIRST_NAME, LAST_NAME
FROM DEVELOPERS
JOIN FRONT_SKILLS ON SKILL_CODE & CODE
ORDER BY ID;
📌 TMI
이걸 비트마스크 연산하면 DISTINCT를 안 써도 된다.
SELECT ID, EMAIL, FIRST_NAME, LAST_NAME
FROM DEVELOPERS
WHERE SKILL_CODE & (
SELECT
SUM(CODE)
FROM
SKILLCODES
WHERE
CATEGORY = 'Front End'
)
ORDER BY ID;
이렇게 하면 JOIN을 안 쓰고, WHERE 절에 하나의 값만 비교하기 때문에 중복이 생기지 않기 때문이다. 아래와 같이 서브쿼리에서 Front End 스킬들의 코드 합계를 숫자 하나로 반환한다.
SELECT SUM(CODE)
FROM SKILLCODES
WHERE CATEGORY = 'Front End'
예를 들면 (예: HTML=1, CSS=2, JS=4라면 1+2+4=7)
그럼 메인쿼리 WHERE절은 아래와 같이 연산이 이루어진다.
WHERE SKILL_CODE & 7
→ 각 개발자의 SKILL_CODE와 7을 비트 AND 연산해서 0보다 크면 조건을 만족한다.
→ 개발자 1명은 조건을 만족하든지 안 하든지 결과에 한 번만 나온다.
JOIN은 "N행 매칭 → 중복 발생"이라 DISTINCT 필요
SUM은 "단일 값 조건 → 중복 없음"이라 DISTINCT 불필요
'코딩테스트 > SQL테스트' 카테고리의 다른 글
[프로그래머스] (MySQL) 입양 시각 구하기(2) 문제풀이 (4) | 2025.08.19 |
---|---|
[프로그래머스] (MySQL) 조건별로 분류하여 주문상태 출력하기 (4) | 2025.08.19 |
[프로그래머스] (MySQL) 그룹별 조건에 맞는 식당 목록 출력하기 문제풀이 (5) | 2025.08.17 |
[프로그래머스] (MySQL) 노선별 평균 역 사이 거리 조회하기 (6) | 2025.08.14 |
[프로그래머스] (MySQL) 가격대 별 상품 갯수 구하기 (5) | 2025.08.12 |