안녕하세요! 새로 나온 SQL의 마지막 문제를 해결하려 왔습니다.
이번 문제는 꽤 많은 시간을 걸려서 푼 만큼 성취감 높았습니다ㅎㅎ
https://school.programmers.co.kr/learn/courses/30/lessons/276036
1. Front End 기술을 가지면서 python 능력을 가진 사람 리스트 구하기
SELECT DISTINCT(ID), FIRST_NAME, LAST_NAME, EMAIL, SKILL_CODE
FROM DEVELOPERS D, SKILLCODES S
WHERE 1 = 1
AND (D.SKILL_CODE & S.CODE) > 0
AND SKILL_CODE & (SELECT S.CODE FROM SKILLCODES S WHERE NAME = 'Python') > 0
AND S.CATEGORY = 'Front End';
2. C# 개발자 구하기
SELECT DISTINCT(ID), FIRST_NAME, LAST_NAME, EMAIL, SKILL_CODE
FROM DEVELOPERS D, SKILLCODES S
WHERE 1 = 1
AND (D.SKILL_CODE & S.CODE) > 0
AND S.NAME = 'C#'
3. 그 외의 프론트 개발자
SELECT DISTINCT(ID), FIRST_NAME, LAST_NAME, EMAIL, SKILL_CODE
FROM DEVELOPERS D, SKILLCODES S
WHERE 1 = 1
AND (D.SKILL_CODE & S.CODE) > 0
AND S.CATEGORY = 'Front End';
4. CASE WHEN 구문을 통해 GRADE 표시
(1) A에 해당하는 개발자들 A로 표시하기
SELECT CASE WHEN ID IN ( SELECT DISTINCT(ID)
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND SKILL_CODE & (SELECT S.CODE FROM SKILLCODES S WHERE NAME = 'Python') > 0
AND S.CATEGORY = 'Front End'
) THEN 'A'
ELSE 'F' END GRADE
,ID
,EMAIL
FROM DEVELOPERS D;
(2) C랑 합쳐서 표시하고 UNION을 통해 B랑 합치기
원래는 아래와 같이 코드를 짰었으나...
(SELECT CASE WHEN ID IN ( SELECT DISTINCT(ID)
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND SKILL_CODE & (SELECT S.CODE FROM SKILLCODES S WHERE NAME = 'Python') > 0
AND S.CATEGORY = 'Front End'
) THEN 'A'
ELSE 'C' END GRADE
,ID
,EMAIL
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND S.CATEGORY = 'Front End'
GROUP BY ID, EMAIL)
UNION
(SELECT 'B' GRADE
,ID
,EMAIL
FROM DEVELOPERS D, SKILLCODES S
WHERE 1 = 1
AND (D.SKILL_CODE & S.CODE) > 0
AND S.NAME = 'C#'
GROUP BY ID, EMAIL)
ORDER BY GRADE, ID;
실패해서 분석해보니, 아마 C#+Front End 기술이 있으면 C로 분류되는 것 같았습니다.
그래서
(3) A,B,C 모두 하나의 SELECT 절에서 CASE WHEN으로 구분
WITH TMP AS (
SELECT CASE WHEN ID IN ( SELECT DISTINCT(ID)
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND SKILL_CODE & (SELECT S.CODE FROM SKILLCODES S WHERE NAME = 'Python') > 0
AND S.CATEGORY = 'Front End'
GROUP BY ID
) THEN 'A'
WHEN ID IN ( SELECT DISTINCT(ID)
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND S.NAME = 'C#'
GROUP BY ID
) THEN 'B'
WHEN ID IN ( SELECT DISTINCT(ID)
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND S.CATEGORY = 'Front End'
GROUP BY ID
) THEN 'C'
END GRADE
,ID
,EMAIL
FROM DEVELOPERS D
GROUP BY ID, EMAIL
)
SELECT *
FROM TMP
WHERE GRADE IS NOT NULL
ORDER BY GRADE, ID;
WITH TMP AS (
SELECT CASE WHEN ID IN ( SELECT DISTINCT(ID)
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND SKILL_CODE & (SELECT S.CODE FROM SKILLCODES S WHERE NAME = 'Python') > 0
AND S.CATEGORY = 'Front End'
GROUP BY ID
) THEN 'A'
WHEN ID IN ( SELECT DISTINCT(ID)
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND S.NAME = 'C#'
GROUP BY ID
) THEN 'B'
WHEN ID IN ( SELECT DISTINCT(ID)
FROM DEVELOPERS D, SKILLCODES S
WHERE (D.SKILL_CODE & S.CODE) > 0
AND S.CATEGORY = 'Front End'
GROUP BY ID
) THEN 'C'
END GRADE
,ID
,EMAIL
FROM DEVELOPERS D
GROUP BY ID, EMAIL
)
SELECT *
FROM TMP
WHERE GRADE IS NOT NULL
ORDER BY GRADE, ID;
집합연산자인 UNION을 통해 B를 합치려고 했으나 C#+Front End 기술이 있으면 C로 분류되는 문제가 발생했습니다.
집합연산자 대신 스칼라 서브쿼리와 임시테이블을 사용해서 다르게 접근하여 풀었습니다.
부족한 글 읽어주셔서 감사합니다.
잘못된 부분 혹은 개선할만한 부분에 대한 댓글 항상 환영합니다.