프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
풀이
1. 아이디어
- DEVELOPERS 테이블에서 GRADE별 개발자의 정보를 조회하려 합니다. GRADE는 다음과 같이 정해집니다.
- A : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
- B : C# 스킬을 가진 개발자
- C : 그 외의 Front End 개발자
이 경우, GRADE를 조건별로 설정해주기 위해서는 CASE WHEN THEN END 사용하는 것이 좋을 거라 생각했다.
2. 문제 해결
SELECT SUM(CODE) FROM SKILLCODES WHERE CATEGORY = 'Front End'
CASE WHEN THEN 내에서 카테고리가 Front End인 SKILLCODES를 찾아줬더니 여러 개의 로우데이터가 나오는 문제가 발생했다. 이 문제를 해결하기 위해 SUM(CODE)로 묶어줬는데, 집계함수 SUM을 사용한 이유는 CODE들이 전부 2진수이기 때문에 합에서도 비트연산을 할 수 있기 때문이다.
전체코드
-- 코드를 작성해주세요
SELECT
CASE WHEN (SKILL_CODE & (SELECT SUM(CODE) FROM SKILLCODES WHERE CATEGORY = 'Front End')
AND SKILL_CODE & (SELECT CODE FROM SKILLCODES WHERE NAME = 'Python')) THEN 'A'
WHEN SKILL_CODE & (SELECT CODE FROM SKILLCODES WHERE NAME = 'C#') THEN 'B'
WHEN SKILL_CODE & (SELECT SUM(CODE) FROM SKILLCODES WHERE CATEGORY = "Front End") THEN 'C' END AS 'GRADE', ID, EMAIL
FROM DEVELOPERS
GROUP BY GRADE, ID, EMAIL
HAVING GRADE IS NOT NULL
ORDER BY GRADE, ID;
-- 코드를 작성해주세요
SELECT
CASE WHEN (SKILL_CODE & (SELECT SUM(CODE) FROM SKILLCODES WHERE CATEGORY = 'Front End')
AND SKILL_CODE & (SELECT CODE FROM SKILLCODES WHERE NAME = 'Python')) THEN 'A'
WHEN SKILL_CODE & (SELECT CODE FROM SKILLCODES WHERE NAME = 'C#') THEN 'B'
WHEN SKILL_CODE & (SELECT SUM(CODE) FROM SKILLCODES WHERE CATEGORY = "Front End") THEN 'C' END AS 'GRADE', ID, EMAIL
FROM DEVELOPERS
HAVING GRADE IS NOT NULL
ORDER BY GRADE, ID;
▶ 해당 코드에서는 GROUP BY를 사용하지 않아도 HAVING이 동작한다.
이유는, 집계 값이 아니라서 GROUP BY가 들어갈 필요가 없고, HAVING은 그룹화된 값에 대해서 사용할 수 있으므로 SELECT 절에서 정의한 별칭에 대해서 사용할 수 있다.
-- 코드를 작성해주세요
WITH FRONT AS (
SELECT SUM(CODE)
FROM SKILLCODES
WHERE CATEGORY LIKE 'Front%'
)
SELECT
CASE WHEN (SKILL_CODE & (SELECT * FROM FRONT)
AND SKILL_CODE & (SELECT CODE FROM SKILLCODES WHERE NAME = 'Python')) THEN 'A'
WHEN SKILL_CODE & (SELECT CODE FROM SKILLCODES WHERE NAME = 'C#') THEN 'B'
WHEN SKILL_CODE & (SELECT * FROM FRONT) THEN 'C' END AS 'GRADE', ID, EMAIL
FROM DEVELOPERS
HAVING GRADE IS NOT NULL
ORDER BY GRADE, ID;
▶ 카테고리가 Front End인 SUM(CODE)만 모아놓은 WITH 테이블을 만들어서 구하는 방법도 있다.
-- 코드를 작성해주세요
WITH FRONT AS (
SELECT
CASE WHEN (SKILL_CODE & (SELECT SUM(CODE) FROM SKILLCODES WHERE CATEGORY = 'Front End')
AND SKILL_CODE & (SELECT CODE FROM SKILLCODES WHERE NAME = 'Python')) THEN 'A'
WHEN SKILL_CODE & (SELECT CODE FROM SKILLCODES WHERE NAME = 'C#') THEN 'B'
WHEN SKILL_CODE & (SELECT SUM(CODE) FROM SKILLCODES WHERE CATEGORY = "Front End") THEN 'C' END AS 'GRADE', ID, EMAIL
FROM DEVELOPERS
)
SELECT GRADE, ID, EMAIL
FROM FRONT
WHERE GRADE IS NOT NULL
ORDER BY GRADE, ID;
▶ HAVING 코드를 사용하지 않고도 쿼리문을 짤 수 있는데, WITH절을 사용해서 NULL이 포함된 테이블을 만든 뒤, SELECT문에서 IS NOT NULL을 사용해 포함되지 않는 로우는 제거해주는 방법을 사용했다.
다른 분들의 풀이를 보니 성능을 고려한다면, WITH절을 사용해 Front end / Python / C# 스킬별로 테이블을 만들어 준 뒤 해당 테이블들을 CASE WHEN THEN으로 묶고 SELECT로 출력해주면 된다는 풀이를 봤다.
'코테 > SQL' 카테고리의 다른 글
[프로그래머스] FrontEnd 개발자 찾기 (MySQL) (1) | 2024.12.19 |
---|---|
[프로그래머스] 연간 평가점수에 해당하는 평가 등급 및 성과금 조회하기 (MySQL) (0) | 2024.12.17 |
[프로그래머스] 조건에 맞는 개발자 찾기 (MySQL) (3) | 2024.12.09 |
[프로그래머스] Python 개발자 찾기 (MySQL) (0) | 2024.11.27 |
[Programmers] 조건에 맞는 아이템들의 가격의 총합 구하기 (MySQL) (0) | 2024.06.22 |