본문 바로가기
문제풀이/SQL(My sql)

[문제풀이] 프로그래머스 - 언어별 개발자 분류하기

by kime2 2024. 7. 4.
출처
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제

DEVELOPERS 테이블에서 GRADE별 개발자의 정보를 조회하려 합니다. GRADE는 다음과 같이 정해집니다.

A : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
B : C# 스킬을 가진 개발자
C : 그 외의 Front End 개발자
GRADE가 존재하는 개발자의 GRADE, ID, EMAIL을 조회하는 SQL 문을 작성해 주세요.

결과는 GRADE와 ID를 기준으로 오름차순 정렬해 주세요.

 

문제에 대한 해석

id = D162의 스킬코드는 8452

이진법으로 바꾸10000100000100

 

select conv(skill_code,10,2),skill_code,category, name
from DEVELOPERS cross join SKILLCODES
where id = 'D162'
and (skill_code&CODE)>0

 

cross조인을 통해 개발자가 가지고 있는 스킬을 알 수 있다

풀이(MYSQL)

-- 오답 : grade 조건에 충족하지 않은 개발자 포함됨

select 'A' as GRADE, id, email
from DEVELOPERS 
where (skill_code | (select sum(code)
                 from SKILLCODES
                 where category = 'Front End')) >0
and (skill_code & (select sum(code)
                 from SKILLCODES
                 where NAME = 'Python')) >0
union all           
select 'B' as GRADE, id, email
from DEVELOPERS 
where (skill_code & (select sum(code)
                 from SKILLCODES
                 where NAME = 'C#')) >0
union all   
select 'C' as GRADE, id, email
from DEVELOPERS 
where (skill_code | (select sum(code)
                  from SKILLCODES                
                where category = 'Front End')) > 0
and not (skill_code & (select sum(code)
                  from SKILLCODES
                  where NAME = 'Python'))  -- not Ture(0이 아닌 것)
and not (skill_code & (select sum(code)
                 from SKILLCODES
                   where NAME = 'C#')) -- not Ture(0이 아닌 것)
order by grade, id

 

그러나 D163은 grade기준에 충족되지 못함 : Front End개발자가 아님

 

C grade에 front end개발자중 pathon이 없는 조건을 어떻게 필터링 하는지 모르겠음..ㅠㅠ

-- 정답
SELECT
CASE WHEN EXISTS(SELECT S.CODE FROM SKILLCODES S WHERE S.CODE & D.SKILL_CODE AND S.NAME = 'Python')
AND EXISTS(SELECT S.CODE FROM SKILLCODES S WHERE S.CODE & D.SKILL_CODE AND S.CATEGORY = 'Front End') THEN 'A'
WHEN EXISTS(SELECT S.CODE FROM SKILLCODES S WHERE S.CODE & D.SKILL_CODE AND S.NAME = 'C#') THEN 'B'
WHEN EXISTS(SELECT S.CODE FROM SKILLCODES S WHERE S.CODE & D.SKILL_CODE AND S.CATEGORY = 'Front End') THEN 'C'
ELSE NULL
END AS GRADE, D.ID, D.EMAIL
FROM DEVELOPERS D
HAVING GRADE IS NOT NULL
ORDER BY GRADE, ID

 

작동순서

💡SQL 실행 순서는 From -> Where -> Group by -> Having -> Select -> Order by ->결과반환

 

  1. FROM 절: DEVELOPERS테이블에서 
  2. HAVING 절: GRADE가 null값이 아닌 경우
  3. SELECT 절
    1. SKILLCODES에서 'Python'의 이름을 가진 코드와 개발자의 코드가 일치(?) 하고 'Front End'의 카테고리 코드와 개발자의 코드가 동일한게 있는 경우 'A'
    2. 아니면, SKILLCODES에서'C#'의 이름을 가진 코드와 개발자의 코드가 동일한게 있는 경우 'B'
    3. 아니면, 'Front End'의 카테고리 코드와 개발자의 코드가 동일한게 있을 경우 'C' 
    4. 그 외에는 null값으로 처리하고 grade라는 컬럼에 저장, 
    5. D.ID, D.EMAIL조회
  4. ORDER BY 절:  GRADE, ID순

배운점

  • 비트연산에서 &과 | 의 차이
  • case when exist의 활용

https://www.tcpschool.com/mysql/mysql_operator_bitwise