문제 설명
대장균들은 일정 주기로 분화하며, 분화를 시작한 개체를 부모 개체, 분화가 되어 나온 개체를 자식 개체라고 합니다.
다음은 실험실에서 배양한 대장균들의 정보를 담은 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 |
문제
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 입니다.
정답
select count(*) as Count
from ECOLI_DATA
where GENOTYPE&2 = 0 and (GENOTYPE&1 != 0 or GENOTYPE&4 != 0 )
풀이
비트연산 사용에 대해 모르는 부분이 있어 해설을 참고하게 되었다.
먼저 비트 연산자에 대해 알아보면
기호 | 내용 |
& | AND 연산, 둘 다 참일경우 만족 |
| | OR 연산, 둘 중 하나만 참이여도 만족 |
^ | XOR연산, 둘중 하나만 참일 경우 만족 |
~ | 보수 연산 |
<< | 왼쪽 시프트 연산자, 변수의 값을 왼쪽으로 지정된 비트 수 만큼 이동 |
>> | 오른쪽 시프트 연산자, 변수의 값을 오른쪽으로 지정된 비트 수 만큼 이동 |
여기서 AND연산자인 '&'를 사용한 문제였다.
그리고 조금 헷갈리던 부분인 형질 1,2,3,4에 대한 내용을 조금 더 이해하기 쉬운 방법으로 찾아보았다.
형질 1 = 0001(2) -> 1
형질 2 = 0010(2) -> 2
형질 3 = 0100(2) -> 4
형질 4 = 1000(2) -> 8
형질ID | 2진법 | GENOTYPE | 풀이 |
1 | 1000 | 8 | 1000 -> 8 |
2 | 1111 | 15 | 1000-> 8, 0100->4, 0010->2, 0001-> 1 8 + 4 + 2 + 1 = 15 |
3 | 1 | 1 | 0001 -> 1 |
4 | 1101 | 13 | 1000 -> 8, 0100 -> 4, 0001-> 1 8 + 4 + 1 = 13 |
형질 1,2,3,4 는 2진법 값에서 1의 위치를 나타내는 것 이였고,
따라서 형질 2를 포함하지 않으며 1,3을 포함한 형질을 골라내기위해
WHERE, AND, OR을 사용했다.
where GENOTYPE&2 = 0
1) where GENOTYPE&2 = 0
첫번째로 where 절에서 &연산을 사용 GENOTYPE과 2 두개가 참의 값인 경우가 아닌 것들이라는 조건을 작성하고
and (GENOTYPE&1 != 0 or GENOTYPE&4 != 0 )
2) and (GENOTYPE&1 != 0 or GENOTYPE&4 != 0 )
첫번째 조건인 형질2가 아닌 것에 and 를 사용해 두번째 조건으로 1과 4가 FALSE가 아닌 경우를 사용해
형질 2를 포함하지 않으며 1이나 3을 포함한 형질ID를 찾을 수 있었다.
비트연산에 대해 모르는 상태로 문제를 만나게 되었고, 어떻게 풀어나가는 지를 중점으로 보고 찾아보며 공부를 하게 된 것 같다.
'SQL' 카테고리의 다른 글
[프로그래머스/MySQL] 경기도에 위치한 식품창고 목록 출력하기 (0) | 2024.07.19 |
---|---|
[프로그래머스/MySQL] 조건에 맞는 회원수 구하기 (0) | 2024.07.18 |
[프로그래머스/MySQL] 자동차 대여 기록에서 장기/단기 대여 구분하기 (0) | 2024.07.11 |
[프로그래머스/MySQL] 서울에 위치한 식당 목록 출력하기 (0) | 2024.07.10 |
[프로그래머스/MySQL] 3월에 태어난 여성 회원 목록 출력하기 (0) | 2024.07.09 |