문제 설명
SKILLCODES
테이블은 개발자들이 사용하는 프로그래밍 언어에 대한 정보를 담은 테이블입니다. SKILLCODES
테이블의 구조는 다음과 같으며, NAME
, CATEGORY
, CODE
는 각각 스킬의 이름, 스킬의 범주, 스킬의 코드를 의미합니다. 스킬의 코드는 2진수로 표현했을 때 각 bit로 구분될 수 있도록 2의 제곱수로 구성되어 있습니다.NAME | TYPE | UNIQUE | NULLABLE |
NAME | VARCHAR(N) | Y | N |
CATEGORY | VARCHAR(N) | N | N |
CODE | INTEGER | Y | N |
DEVELOPERS
테이블은 개발자들의 프로그래밍 스킬 정보를 담은 테이블입니다. DEVELOPERS
테이블의 구조는 다음과 같으며, ID
, FIRST_NAME
, LAST_NAME
, EMAIL
, SKILL_CODE
는 각각 개발자의 ID, 이름, 성, 이메일, 스킬 코드를 의미합니다. SKILL_CODE
컬럼은 INTEGER 타입이고, 2진수로 표현했을 때 각 bit는 SKILLCODES
테이블의 코드를 의미합니다.NAME | TYPE | UNIQUE | NULLABLE |
ID | VARCHAR(N) | Y | N |
FIRST_NAME | VARCHAR(N) | N | Y |
LAST_NAME | VARCHAR(N) | N | Y |
EMAIL | VARCHAR(N) | Y | N |
SKILL_CODE | INTEGER | N | N |
예를 들어 어떤 개발자의
SKILL_CODE
가 400 (=b'110010000')이라면, 이는 SKILLCODES
테이블에서 CODE가 256 (=b'100000000'), 128 (=b'10000000'), 16 (=b'10000') 에 해당하는 스킬을 가졌다는 것을 의미합니다.문제
DEVELOPERS
테이블에서 Python이나 C# 스킬을 가진 개발자의 정보를 조회하려 합니다. 조건에 맞는 개발자의 ID, 이메일, 이름, 성을 조회하는 SQL 문을 작성해 주세요.결과는 ID를 기준으로 오름차순 정렬해 주세요.
예시
예를 들어
SKILLCODES
테이블이 다음과 같고,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 |
DEVELOPERS
테이블이 다음과 같다면ID | FIRST_NAME | LAST_NAME | EMAIL | 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
테이블에 포함된 개발자 중 Python 스킬이나 C# 스킬을 가진 개발자의 정보가 결과에 나와야 합니다.ID | EMAIL | FIRST_NAME | LAST_NAME |
D162 | cade_cunningham@grepp.co | Cade | Cunningham |
D164 | kelly_grant@grepp.co | Kelly | Grant |
D165 | jerami_edwards@grepp.co | Jerami | Edwards |
- D162번 개발자의 경우 SKILL_CODE가 8452 = 8192 + 256 +4 로 Vue, Python, Cpp 스킬을 보유하고 있습니다.
- D164번 개발자의 경우 SKILL_CODE가 1024 로 C# 스킬을 보유하고 있습니다.
- D165번 개발자의 경우 SKILL_CODE가 400 = 256 + 128 + 16 으로 Python, Java, JavaScript 스킬을 보유하고 있습니다.
문제 풀이
select distinct(d.ID), d.email, d.first_name, d.last_name
from developers d
join skillcodes s
on d.skill_code & s.code
where s.name = 'python' or s.name = 'c#'
order by id asc;


비트 연산자 &
SQL에서 사용하는 **비트 연산자(Bitwise Operators)**는 숫자 데이터를 비트 단위로 비교하거나 조작할 때 사용돼. 주로
INT
타입 같은 정수형 컬럼에서 많이 써.✅ 주요 비트 연산자들
연산자 | 의미 | 예시 ( a = 6 , b = 3 ) | 결과 |
& | AND (둘 다 1이면 1) | a & b (6 & 3 ) | 2 |
` | ` | OR (하나라도 1이면 1) | a | b (6 | 3 ) |
^ | XOR (다르면 1) | a ^ b (6 ^ 3 ) | 5 |
~ | NOT (반전) | ~a | -7 (보수 연산) |
<< | 왼쪽 시프트 | a << 1 | 12 |
>> | 오른쪽 시프트 | a >> 1 | 3 |
예시 1: &
연산
sql
복사편집
SELECT * FROM user_tb
WHERE permission & 4 = 4;
- 위 쿼리는
permission
컬럼의 비트값 중4
(즉,100
) 비트가 켜져 있는 행만 조회.
- 권한 플래그나 옵션 설정 같은 걸 비트로 저장할 때 유용해!
예시 2: |
연산 (비트를 추가하는 느낌)
sql
복사편집
-- 권한 2(010)과 4(100)를 모두 추가
SELECT (2 | 4) AS result; -- 결과: 6 (110)
예시 3: 시프트 연산
sql
복사편집
SELECT (1 << 2) AS result; -- 결과: 4 (0001 -> 0100)
왼쪽으로 2칸 밀면 값이 4배가 되는 원리.
중복제거
SQL에서 중복 제거하려면 상황에 따라 여러 가지 방법이 있어. 대표적으로는
DISTINCT
, GROUP BY
, ROW_NUMBER()
같은 걸 사용할 수 있어. 간단하게 정리해줄게!✅ 1. DISTINCT
– 완전 중복 제거
sql
복사편집
SELECT DISTINCT column_name FROM table_name;
- 특정 컬럼 값의 중복된 행을 제거하고 고유한 값만 가져올 때 사용.
예시:
sql
복사편집
SELECT DISTINCT category FROM products;
→
products
테이블에서 중복된 카테고리를 제거하고 한 번씩만 출력.✅ 2. GROUP BY
– 그룹핑하면서 중복 제거
sql
복사편집
SELECT column_name, COUNT(*) FROM table_name GROUP BY column_name;
- 중복된 값을 하나로 묶고, 갯수를 세거나 집계함수를 사용할 때.
예시:
sql
복사편집
SELECT user_id, COUNT(*) FROM orders GROUP BY user_id;
→ 각 사용자별로 주문 개수를 보여줌.
✅ 3. ROW_NUMBER()
– 중복 중에서 하나만 선택
- 복잡한 경우 (예: 중복된 행 중에 가장 최신 것만 가져오고 싶을 때) 사용.
sql
복사편집
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY email ORDER BY created_at DESC) AS rn
FROM users
)
SELECT * FROM ranked WHERE rn = 1;
→ 같은 이메일을 가진 사용자 중
created_at
기준으로 최신 1개만 가져옴.Share article