프로그래머스 SQL - 특정 형질을 가지는 대장균 찾기(비트 연산자 &)
비트 연산자란?
데이터를 비트 단위로 연산, 0과 1로 표현이 가능한 정수 타입만 비트 연산이 가능
기능에 따라 논리 연산자, 이동 연산자로 구분
논리 연산자
- &: 대응되는 비트가 모두 1이면 1을 반환 (AND 연산)
- |: 대응되는 비트 중 하나라도 1이면 1을 반환 (OR 연산)
- ^: 대응되는 비트가 서로 다르면 1을 반환 (XOR 연산)
- ~: 비트를 1이면 0으로, 0이면 1로 반전시킴 (NOT 연산)
논리 연산자는 대상이 boolean일 경우 일반 논리 연산자로 활용되지만 대상이 정수형인 경우 위와 같이 비트 논리 연산자로 활용
두 값을 비트 단위로 나열한 뒤, 각 자릿수를 비트 연산자로 연산, 각 자릿수의 연산은 독립적이며 다른 자릿수에 영향 안 줌
ex) 0 & 0 → 1
0 & 1 → 0
1 & 1 → 1
1 | 1 → 1
0 | 1 → 1
0 | 0 → 0
0 ^ 0 → 0
0 ^ 1 → 1
1 ^ 1 → 0
0 ~ → 1
1 ~ → 0 이런식이다
https://wiki1.kr/index.php/%EB%B9%84%ED%8A%B8%EC%97%B0%EC%82%B0%EC%9E%90
위키원
위키원
wiki1.kr
-- 비트 연산자 활용 예시
a = 40, b = 13
-- 이를 이진법으로 표현하면
a = 101000 → 2^5 + 2^3
b = 001101 → 2^3 + 2^2 + 2^0
a & b = 101000 & 001101 = 011010 → 0
--&연산자는 비트가 모두 1이어야 1 반환하니까 얘는 0
해당 개념을 사용한 문제 풀기
프로그래머스 MySQL Level.1 특정 형질을 가지는 대장균 찾기
https://school.programmers.co.kr/learn/courses/30/lessons/301646
문제 설명
대장균들은 일정 주기로 분화하며, 분화를 시작한 개체를 부모 개체, 분화가 되어 나온 개체를 자식 개체라고 합니다.
다음은 실험실에서 배양한 대장균들의 정보를 담은 ECOLI_DATA 테이블입니다. ECOLI_DATA 테이블의 구조는 다음과 같으며, ID, PARENT_ID, SIZE_OF_COLONY, DIFFERENTIATION_DATE, GENOTYPE 은 각각 대장균 개체의 ID, 부모 개체의 ID, 개체의 크기, 분화되어 나온 날짜, 개체의 형질을 나타냅니다.
COLUMN NAME | TYPE | NULLABLE |
ID | INTEGER | FALSE |
PARENT_ID | INTEGER | TRUE |
SIZE_OF_COLONY | INTEGER | FALSE |
DIFFERENTIATION_DATE | DATE | FALSE |
GENOTYPE | INTEGER | FALSE |
최초의 대장균 개체의 PARENT_ID는 NULL 값입니다.
문제
2번 형질이 보유하지 않으면서 1번이나 3번 형질을 보유하고 있는 대장균 개체의 수(COUNT)를 출력하는 SQL 문을 작성해주세요. 1번과 3번 형질을 모두 보유하고 있는 경우도 1번이나 3번 형질을 보유하고 있는 경우에 포함합니다.
예를 들어 ECOLI_DATA 테이블이 다음과 같다면
ID | PARENT_ID | SIZE_OF_COLONY | DIFFERENTIATION_DATE | GENOTYPE |
1 | NULL | 10 | 2019/01/01 | 8 |
2 | NULL | 2 | 2019/01/01 | 15 |
3 | 2 | 100 | 2020/01/01 | 1 |
4 | 2 | 16 | 2020/01/01 | 13 |
각 대장균 별 형질을 2진수로 나타내면 다음과 같습니다.
ID 1 : 1000₍₂₎
ID 2 : 1111₍₂₎
ID 3 : 1₍₂₎
ID 4 : 1101₍₂₎
각 대장균 별 보유한 형질을 다음과 같습니다.
ID 1 : 4
ID 2 : 1, 2, 3, 4
ID 3 : 1
ID 4 : 1, 3, 4
따라서 2번 형질이 없는 대장균 개체는 ID 1, ID 3, ID 4 이며
이 중 1번이나 3번 형질을 보유한 대장균 개체는 ID 3, ID 4입니다.
따라서 결과는 다음과 같아야 합니다.
출력 결과
COUNT |
2 |
문제 풀이 접근
1. 개체 수를 출력하는거니까 SELECT COUNT(*)가 들어가야 함
2. '2번 형질이 보유하지 않으면서 1번이나 3번 형질을 보유하고 있는'라는 조건절이 WHERE 다음에 들어가야 함
3. n번 형질은 2진수로 변경했을 때 자릿수를 말하는 것, ex) 8 = 0100(2) → 3번 형질 존재
조건절에 비트 연산자를 입력해야 함
4. 출력 결과를 보면 칼럼명이 COUNT로 새로 지정되어있음
SELECT COUNT(*) as COUNT --새 칼럼명 지정
FROM ecoli_data
WHERE (비트 연산자 조건문)
조건문 코드 작성
2번 형질은 보유 X, genotype & 0010(2) = 0 (연산의 결과값이 0000이므로)
그리고
1번 혹은 3번 형질은 보유, 그니까 연산의 결과값이 0이 아니면됌 genotype & 0100(2) != 0 OR genotype & 0001(2) != 0
최종 코드
SELECT COUNT(id) AS 'COUNT'
FROM ecoli_data
WHERE genotype & 2 = 0
AND (genotype & 4 != 0 OR gebotype & 1 != 0)