문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/276035
select DISTINCT d.id,d.email,d.first_name,d.last_name from developers as d left join skillcodes as s on s.category='Front End' where d.skill_code & s.code order by d.id;
아래와 같은 SKILLCODES
테이블과 DEVELOPERS
테이블이 있다.
NAME | CATEGORY | CODE |
---|---|---|
C++ | Back End | 4 |
JavaScript | Front End | 16 |
Java | Back End | 128 |
Python | Back End | 256 |
C# | Back End | 1024 |
React | Front End | 2048 |
Vue | Front End | 8192 |
Node.js | Back End | 16384 |
ID | FIRST_NAME | LAST_NAME | SKILL_CODE | |
---|---|---|---|---|
D165 | Jerami | Edwards | jerami_edwards@grepp.co | 400 |
D161 | Carsen | Garza | carsen_garza@grepp.co | 2048 |
D164 | Kelly | Grant | kelly_grant@grepp.co | 1024 |
D163 | Luka | Cory | luka_cory@grepp.co | 16384 |
D162 | Cade | Cunningham | cade_cunningham@grepp.co | 8452 |
DEVELOPERS 테이블의 SKILL_CODE는 이진수로 나타냈을때 각 비트는 SKILLCODES의 테이블의 code
에 대응된다. 스킬코드 400을
2진수로 나타내었을때 110010000 가 되고 이를 풀어서 쓰면
이렇게 된다. 즉, skill_code가 400인 ID D165은 C++과 Java,Python을 할수있다는 뜻이다.
이런방식으로 개발자중 가진 기술의 CATEGORY
가 하나라도 Front End
인 개발자를 찾아내는 문제다.
먼저 DEVELOPERS 테이블에 JOIN으로 SKILLCODES 중 카테고리가 Front End인 컬럼들을 연결한다.
select d.id,d.email,d.first_name,d.last_name from developers as d left join skillcodes as s on s.category='Front End'
그리고 DEVELOPERS 테이블의 SKILL_CODE에 연결한 SKILLCODES 가 포함되어있는지를 판단하기 위해 where 조건에서 & 비트 연산을 수행한다.
# 위 쿼리에서 이어짐
where d.skill_code & s.code order by d.id;
DEVELOPERS
ID | FIRST_NAME | LAST_NAME | SKILL_CODE | |
---|---|---|---|---|
D162 | Cade | Cunningham | cade_cunningham@grepp.co | 8452 |
SKILLCODES
NAME | CATEGORY | CODE |
---|---|---|
JavaScript | Front End | 16 |
React | Front End | 2048 |
Vue | Front End | 8192 |
현재 SKILLCODES 테이블에서 category가 Front End 항목들이다.
skill_code 8452
에서 8192 를 & 연산 하면 결과 값으로 8192가 나왔다 즉, d.skill_code & s.code
를 실행해서 0(false)이 아닌 값이 나온다면 해당 skill_code에 Front End 코드가 포함되어있다는 뜻이다.
그리고 마지막으로 중복되는 값을 제거하기 위해 select 뒤에 DISTINCT
를 붙여준다.
비트연산은 예전에 사용해본 경험이 있기때문에 어렵지않게 찾아냈다 문제는 front end 스킬이 여러개가 있을경우 결과에서 중복값을 제거하는것이었는데 아직까지 group by
나 having
같은 중복제거 필터링 방법이 익수치 않아서 계속 group by 쪽으로 시도를 해보려다 시간이 꽤나 걸렸고 그냥 중복값을 제거한다. 정도로만 알고있었던 DISTINCT를 써줬더니 통과했던 문제다 사실 아직까지 DISTINCT가 어떻게 중복값을 제거하는지 몰라서 좀더 알아봐야겠다.