문제
https://school.programmers.co.kr/learn/courses/30/lessons/276036
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
[문제 포인트 짚기]
DEVELOPERS 테이블에서 GRADE별 개발자의 정보를 조회. 조건은 아래와 같다.
A : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
B : C# 스킬을 가진 개발자
C : 그 외의 Front End 개발자
GRADE가 존재하는 개발자의 GRADE, ID, EMAIL을 조회하는 SQL 문
GRADE와 ID를 기준으로 오름차순 정렬해 주세요.
SKILLCODES
DEVELOPERS
풀이
1. 비트 연산
DEVELOPERS 테이블의 skill_code안에 어떤 스킬이 들어있는지 확인해야 한다.
이를 위한 방법으로 비트연산을 수행한다. 이를 위해서 문제에서 나온 예시를 살짝 확인해 본다.
예를 들어 어떤 개발자의 SKILL_CODE가 400 (=b'110010000')이라면,
이는 SKILLCODES 테이블에서 CODE가 256 (=b'100000000'), 128 (=b'10000000'), 16 (=b'10000')에
해당하는 스킬을 가졌다는 것을 의미합니다.
1이 있는 자리를 위주로 보면 된다. 400은 256,128,16을 합치면 나오는 수 가된다. 알기 쉽게 세로로 나열해 보았다.
110010000
100000000
010000000
000010000
세로로 보면 1의 위치가 같다. 따라서 AND 연산을 수행한다.
만약 해당 수가 skill_code에 있다면? 자기 자신을 출력하게 된다. 코드로 작성하면 다음과 같다.
WITH CTE AS (
SELECT *
FROM DEVELOPERS d
LEFT JOIN SKILLCODES c
ON d.skill_code & c.CODE <> 0
),
2. GROUP CONCAT
테이블을 보면 GROUP으로 전혀 묶이지 않았다.
그룹으로 묶는 동시에 category와 name안에 들어있는 스킬들을 하나로 엮어줘야 한다.
따라서 다음과 같이 코드를 구성했다.
CTE2 AS (
SELECT ID, FIRST_NAME, LAST_NAME, EMAIL,
GROUP_CONCAT(CATEGORY SEPARATOR ', ') AS CATEGORIES,
GROUP_CONCAT(NAME SEPARATOR ', ') AS NAMES
FROM CTE
GROUP BY ID, FIRST_NAME, LAST_NAME, EMAIL
)
이전에 작성했던 게시글을 참고하면 더 잘 이해할 것 같다. 달라진 점은 SEPARATOR 사용인데
이를 사용하면 각각의 값들 사이에 ,를 넣어주게 된다.
https://itpori.tistory.com/search/group%20concat
Pori_IT
itpori.tistory.com
3. LIKE를 사용해서 조건 확인하기.
CATEGORY와 NAME에 걸린 조건을 다시 확인해 보자.
A : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
B : C# 스킬을 가진 개발자
C : 그 외의 Front End 개발자
GRADE가 존재하는 개발자의 GRADE, ID, EMAIL을 조회하는 SQL 문
GRADE와 ID를 기준으로 오름차순 정렬해 주세요.
이를 위해서 CASE WHEN과 LIKE를 같이 사용해 조건을 걸어주었다.
CTE3 AS (
SELECT
CASE
WHEN CATEGORIES LIKE '%Front End%' AND NAMES LIKE '%Python%' THEN 'A'
WHEN NAMES LIKE '%C#%' THEN 'B'
WHEN CATEGORIES LIKE '%Front End%' THEN 'C'
END AS GRADE,
ID,
EMAIL
FROM CTE2
)
SELECT *
FROM CTE3
WHERE GRADE IS NOT NULL
ORDER BY GRADE,ID
[전체 코드]
WITH CTE AS (
SELECT *
FROM DEVELOPERS d
LEFT JOIN SKILLCODES c
ON d.skill_code & c.CODE <> 0
),
CTE2 AS (
SELECT ID, FIRST_NAME, LAST_NAME, EMAIL,
GROUP_CONCAT(CATEGORY SEPARATOR ', ') AS CATEGORIES,
GROUP_CONCAT(NAME SEPARATOR ', ') AS NAMES
FROM CTE
GROUP BY ID, FIRST_NAME, LAST_NAME, EMAIL
),
CTE3 AS (
SELECT
CASE
WHEN CATEGORIES LIKE '%Front End%' AND NAMES LIKE '%Python%' THEN 'A'
WHEN NAMES LIKE '%C#%' THEN 'B'
WHEN CATEGORIES LIKE '%Front End%' THEN 'C'
END AS GRADE,
ID,
EMAIL
FROM CTE2
)
SELECT *
FROM CTE3
WHERE GRADE IS NOT NULL
ORDER BY GRADE,ID
'코딩테스트 > SQL' 카테고리의 다른 글
SQL > 프로그래머스 276035 [level 4] FrontEnd 개발자 찾기 (0) | 2024.07.31 |
---|---|
SQL > 프로그래머스 131124 [level 4] 그룹별 조건에 맞는 식당 목록 출력하기 (0) | 2024.07.30 |
SQL > 프로그래머스 59413 [level 4] 입양 시각 구하기(2) (0) | 2024.07.01 |
SQL > 프로그래머스 151139 [level 3] 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기 (0) | 2024.06.27 |
SQL > 프로그래머스 PCSQL (0) | 2024.06.24 |