안녕하세요
힐링 겸 SQL 문제로 찾아왔습니다.
바로 ㄱㅂㅈㄱ!
https://school.programmers.co.kr/learn/courses/30/lessons/276034
큰 문제는 아래 부분이 생소해서 해맸습니다.
예를 들어 어떤 개발자의 SKILL_CODE가 400 (=b'110010000')이라면, 이는 SKILLCODES 테이블에서 CODE가 256 (=b'100000000'), 128 (=b'10000000'), 16 (=b'10000') 에 해당하는 스킬을 가졌다는 것을 의미합니다.
즉, 400(110010000) = 256(100000000) + 128(10000000) + 16(100000) 라는 의미죠.
이는 비트 연산자(&)를 사용해서 해결할 수 있습니다.
비트 연산자는 논리 연산자와 비슷하지만, 비트(bit) 단위로 논리 연산을 수행합니다.
또한, 비트 단위로 전체 비트를 좌측이나 우측으로 이동시킬 때도 사용합니다. (연산자 우선순위대로 나열 &가 우선순위 1등)
// 출력: 8
// 첫 번째 비트만이 둘 다 1이므로, 연산 결과는 b'1000'이 됨.
SELECT b'1000' & b'1111';
그래서 WHERE 절에 다음과 같은 조건을 넣어주면 됩니다.
WHERE (SKILL_CODE & S.CODE) > 0
SELECT ID
,EMAIL
,FIRST_NAME
,LAST_NAME
FROM DEVELOPERS D, SKILLCODES S
WHERE 1 = 1
AND (SKILL_CODE & S.CODE) > 0
AND NAME IN ('Python', 'C#')
ORDER BY ID;
https://school.programmers.co.kr/learn/courses/30/lessons/276035
앞의 문제에 CATEGORT 조건절만 추가하면 될 줄 알았으나,
아무리 봐도 틀린 것 같지 않은데, 결국 질문하기에서 똑똑한 선생님이 해주신 말을 보고 깨달았습니다.
바로, 한 개발자는 여러 언어 기술을 가질 수 있는데, 이로써 여러 프론트엔드 기술을 가진 한 개발자의 정보가 중복으로 나온다는 것이죠.
이는 SKILLCODES 테이블과 DEVELOPERS 테이블이 N:1(다대일) 관계이기 때문에 발생하는 문제입니다.
어떻게 해결할 것인가?
나는 일단 한 개발자에 대해 ID, EMAIL, 이름들이 계속 중복된다는 점을 보고
GROUP BY ID, EMAIL, FIRST_NAME, LAST_NAME
이렇게 그룹함수를 써서 해결했습니다. 하지만 여러 컬럼을 그룹핑 하는 것은 데이터의 양이 많을 수록 성능 저하를 끌어냅니다.
그래서 질문하기의 선생님들의 코드를 봤습니다.
select id, email, first_name, last_name
from developers d
where skill_code & (
select sum(code)
from skillcodes
where category = 'Front End'
group by category //그룹 함수가 없어도 CATEGORY가 이미 WHERE 절에서 Front End 하나로 좁혀져서 결과가 나온다.
)
order by id
SELECT ID
,EMAIL
,FIRST_NAME
,LAST_NAME
FROM DEVELOPERS D, SKILLCODES S
WHERE 1 = 1
AND (D.SKILL_CODE & S.CODE) > 0
AND CATEGORY = 'Front End'
GROUP BY ID, EMAIL, FIRST_NAME, LAST_NAME
ORDER BY ID;
조건에 맞는 개발자 찾기
비트연산자가 익숙치 않아서 해맸습니다.
비트 연산자를 공부해서 해결했습니다
FrontEnd 개발자 찾기
테이블간의 관계를 생각하지 않고 풀어서 해맸습니다.
관계를 생각하면서 쿼리를 짰습니다.
부족한 글 읽어주셔서 감사합니다.
잘못된 부분 혹은 개선할만한 부분에 대한 댓글 항상 환영합니다.