728x90
문제
https://school.programmers.co.kr/learn/courses/30/lessons/276036
- GRADE별 개발자 정보 조회.
- GRADE 기준
- A : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
- B : C# 스킬을 가진 개발자
- C : 그 외의 Front End 개발자
- GRADE가 존재하는 개발자의 GRADE, ID, EMAIL을 조회하는 SQL 문 작성
- 결과는 GRADE와 ID 기준 오름차순 정렬
테이블
SKILLCODES | |
DEVELOPERS |
풀이과정
# DEVELOPER 테이블과 SKILLCODES 테이블 조인
- DEVELOPER 테이블의 SKILL_CODE와
SKILLCODES 테이블의 CODE를 비트연산자 & 를 사용해서 조인하면
해당 SKILL_CODE에 포함되어 있는(해당 자릿수가 1인) 스킬들을 확인할 수 있음
1 2 3 4 | SELECT * FROM DEVELOPERS D JOIN SKILLCODES S ON D.SKILL_CODE & S.CODE ORDER BY ID | cs |
# 다른 사람 풀이 (1)
- GROUP_CONCAT 함수를 이용해 (ID와 EMAIL 별로) 스킬 이름과 카테고리를 구분자(,)로 묶음 >> skills, dev_skills
- GROUP_CONCAT(컬럼명, ',', 컬럼명) : 스킬 이름과 카테고리를 , (콤마)로 연결함
- FIND_IN_SET 함수를 이용해 위에서 GROUP_CONCAT으로 묶은 문자열 안에서 조건에 맞는 문자를 찾음. (매칭되는 문자가 있으면 0보다 클 것.) 문제에서 제시한 GRADE 조건에 따라서 A, B, C 등급 구분 >> grade_dev
- FIND_IN_SET(str, str_list) : 콤마로 구분되어 있는 str_list에서 매칭되는 str 문자가 있는지 확인해줌.
매칭되는 문자가 있는 경우, 해당 문자의 자리 번호를 반환하고, 없으면 0 반환. - 마지막에 GRADE와 ID로 정렬 조건 주면 끝!
- FIND_IN_SET(str, str_list) : 콤마로 구분되어 있는 str_list에서 매칭되는 str 문자가 있는지 확인해줌.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | SELECT GRADE, ID, EMAIL FROM(SELECT CASE WHEN (FIND_IN_SET('Python', skills) > 0 AND FIND_IN_SET('Front End', skills) > 0) THEN 'A' WHEN (FIND_IN_SET('C#', skills) > 0) THEN 'B' WHEN (FIND_IN_SET('Front End', skills) > 0) THEN 'C' END AS GRADE, ID, EMAIL FROM (SELECT D.ID, D.EMAIL, GROUP_CONCAT(S.NAME, ',', S.CATEGORY) AS skills FROM DEVELOPERS D JOIN SKILLCODES S ON (D.SKILL_CODE & S.CODE) = S.CODE GROUP BY D.ID, D.EMAIL ) AS dev_skills ) AS grade_dev WHERE GRADE IS NOT NULL ORDER BY GRADE, ID; | cs |
https://school.programmers.co.kr/questions/76142
# 다른 사람 풀이 (2)
1 2 3 | # A등급 (하단 정답 코드 일부 발췌) CASE WHEN SUM(CASE WHEN B.NAME='Python' THEN 3 WHEN B.CATEGORY = 'Front End' THEN 1 ELSE 0 END) > 3 THEN 'A' | cs |
- A등급 : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
- 이 때 Front End 스킬을 가진 경우 1, 아니면 0을 반환함.
- Python 스킬을 가진 경우 최소한 3 이라는 숫자를 부여해야 하고, 전체 SUM 값도 3 초과 (> 3)가 되게 해야 함.
(3 이상의 임의의 숫자는 모두 가능)
- 최소한 3이라는 숫자를 부여해야 하는 이유는,
SKILLCODES 테이블에 카테고리가 Front End인 경우는 3가지(JavaScript, React, Vue)이기 때문. - A등급이 되기 위해서는 적어도 한 가지 이상의 Front End 스킬과 Python 스킬을 가지면 됨.
- (예시) 만약 한 개발자가 Front End 세 가지 스킬을 모두 가지고 있는 경우에는 각각 1을 반환하게 되고,
이 때 Python 스킬에도 1이라는 숫자를 부여하면 SUM값은 앞서 Front End 스킬 3개 반환값(3)과 Python 스킬 반환값(1)을 합한 4가 되므로 3 초과 조건을 통과해 A등급이 부여됨. - 하지만!! 만약 한 개발자가 Front End 스킬 중 한 개의 스킬만 가지고 있으면 SUM 값은 1이 되고,
여기에 Python 스킬에도 1이라는 숫자를 부여하면 SUM값은 2가 되고, 3이 초과 조건에 부합하지 않아 (문제에서 요구한 A등급 기준에 적합함에도) A등급을 받을 수 없게 됨. - 이런 경우까지 모두 고려해봤을 때, Python 스킬에 적어도 3이라는 숫자를 부여함으로써 Python 스킬과 더불어 Front End 스킬 중 어느 하나라도 보유한 사람이라면 A등급이 나오게 해야 함.
- 그 결과 Python 스킬 반환값은 적어도 3이어야 하고, A등급 조건도 3 초과여야 함.
- 최소한 3이라는 숫자를 부여해야 하는 이유는,
- B등급 : C# 스킬을 가진 개발자
- C# 스킬을 가진 경우 1, 그렇지 않은 경우 0을 반환
- C등급 : 그 외의 Front End 개발자
- Front End 스킬을 가진 경우 1, 그렇지 않은 경우 0을 반환
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | SELECT A.GRADE ,A.ID ,A.EMAIL FROM( SELECT A.ID, CASE WHEN SUM(CASE WHEN B.NAME='Python' THEN 3 WHEN B.CATEGORY = 'Front End' THEN 1 ELSE 0 END) > 3 THEN 'A' WHEN SUM(CASE WHEN B.NAME='C#' THEN 1 ELSE 0 END) > 0 THEN 'B' WHEN SUM(CASE WHEN B.CATEGORY = 'Front End' THEN 1 ELSE 0 END) > 0 THEN 'C' ELSE NULL END AS GRADE, MIN(A.EMAIL) AS EMAIL FROM DEVELOPERS A INNER JOIN SKILLCODES B ON A.SKILL_CODE & B.CODE = B.CODE GROUP BY A.ID ) A WHERE A.GRADE IS NOT NULL ORDER BY A.GRADE, A.ID; | cs |
https://school.programmers.co.kr/questions/79636
728x90
'코딩테스트 > SQL 코드카타' 카테고리의 다른 글
MySQL 프로그래머스 | 부모의 형질을 모두 가지는 대장균 찾기 (비트연산자, IN 활용) (1) | 2024.10.10 |
---|---|
MySQL 프로그래머스 | 특정 형질을 가지는 대장균 찾기 (비트연산자 활용) (1) | 2024.10.08 |
MySQL 프로그래머스 | 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기 (2) | 2024.09.25 |
MySQL 프로그래머스 | 식품분류별 가장 비싼 식품의 정보 조회하기 (2) | 2024.09.24 |
MySQL 프로그래머스 | 입양 시각 구하기2 (SQL식 반복문 : RECURSIVE 재귀 가상테이블 만들기) (3) | 2024.09.23 |
댓글