| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Java IO
- 도커 엔진
- container
- RDB
- 스레드
- 인프런
- 멀티 쓰레드
- java
- mysql
- 실전 자바 고급 1편
- 컨테이너
- 자바
- SQL
- Kubernetes
- 김영한
- 자바 입출력 스트림
- 쿠버네티스
- 알고리즘
- 동시성
- 스트림
- 함수형 인터페이스
- 시작하세요 도커 & 쿠버네티스
- 람다
- Docker
- 쓰레드
- 데이터베이스
- Thread
- 도커
- lambda
- 자료구조
- Today
- Total
쌩로그
[프로그래머스 - SQL] 특정 형질을 가지는 대장균 찾기 본문
목록
- 포스팅 개요
- 문제
- 풀이
1. 포스팅 개요
해당 포스팅은 프로그래머스의 MySQL Lv1 특정 형질을 가지는 대장균 찾기 문제를 풀이한 것이다.
2. 문제
문제 설명
대장균들은 일정 주기로 분화하며, 분화를 시작한 개체를 부모 개체, 분화가 되어 나온 개체를 자식 개체라고 합니다.
다음은 실험실에서 배양한 대장균들의 정보를 담은 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 |
3. 풀이
SELECT count(GENOTYPE) AS COUNT
FROM ECOLI_DATA
WHERE 1=1
AND GENOTYPE & 2 != 2
AND GENOTYPE & 5 != 0;
MySQL 의 AND(&) 연산을 활용하여 풀었다.
AND 연산 같은 경우 특정 데이터의 수와 & 의 우측 피연산자와 비트 연산을 하여, 동일한 부분을 찾아서 그 값을 반환한다.
예를 들어, number & 5 를 했을 때,
5는 2진수로 0101이다.
1 ~ 8까지 5와 AND 연산을 한다고 가정해보자.
5는 이진수로 0101이다.
1부터 8까지의 이진수는 다음과 같다.
8 1000
7 0111
6 0110
5 0101
4 0100
3 0011
2 0010
1 0001
그래서 이를 연산해보면
8 1000 & 0101 = 0 일치하는 비트가 없으므로 0이다.
7 0111 & 0101 = 5 1비트와 3비트가 일치하여 1 + 100(이진수는 100 십진수로 4) 로 5이다.
6 0110 & 0101 = 4 3비트만 일치하여 4이다.
5 0101 & 0101 = 5 모든 비트가 일치하여 5이다.
4 0100 & 0101 = 4 3비트만 일치하여 4이다.
3 0011 & 0101 = 1 1비트만 일치하여 1이다.
2 0010 & 0101 = 0 일치하는 비트가 없으므로 0이다.
1 0001 & 0101 = 1 1비트만 일치하여 1이다.
따라서 문제를 파악하여 SQL 문을 작성해보면,
SELECT COUNT(GENOTYPE) AS COUNT
FROM ECOLI_DATA
WHERE 1=1
AND GENOTYPE & 2 != 2
AND GENOTYPE & 5 != 0;
이렇게 하니 통과되었다.
2의 형질을 가지지 않아야 하기 때문에 2와 연산을 하여 2 가 되면 안 된다.
뿐만 아니라, 1비트와 3비트에는 둘 다 있던가, 혹은 하나만 있어야 하기 때문에, 2비트엔 없고, 1비트와 3비트를 가지는 5를 연산을 했다.
그래서 위의 SQL문으로 통과했다.