프로그래머스에 비트 연산을 해야하는 MySQL문제가 종종 보이는데요. 정리해놓으면 좋을 것 같아서 문제 풀이를 한번 작성해 보겠습니다.
https://school.programmers.co.kr/learn/courses/30/lessons/301646
문제 : 2번 형질을 보유하지 않으면서 1번이나 3번 형질을 보유하고 있는 대장균 개체의 수(COUNT)를 출력하는 SQL 문을 작성해주세요. 1번과 3번 형질을 모두 보유하고 있는 경우도 1번이나 3번 형질을 보유하고 있는 경우에 포함합니다.
[1] 2진법으로 계산해 보기
먼저 각 열의 GENOTYPE의 수를 2진법으로 바꾸어 출력해 보겠습니다. 주어진 정수 데이터에 BIN() 함수를 사용하면 정수를 2진법 수로 변환한 결과를 출력합니다.
SELECT BIN(GENOTYPE) AS GENOTYPE_BIN
FROM ECOLI_DATA
그럼 이제 출력된 결과를 CAST함수를 이용해서 CHAR 데이터타입으로 바꾼 뒤, WHERE문을 사용해서 필터링을 해 보겠습니다.
SELECT COUNT(*) AS `COUNT`
FROM (SELECT ID,
CAST(BIN(GENOTYPE) AS CHAR) AS GENOTYPE_BIN
FROM ECOLI_DATA) A
WHERE A.GENOTYPE_BIN LIKE '1' OR
A.GENOTYPE_BIN LIKE '%10_' OR
A.GENOTYPE_BIN LIKE '%01'
WHERE문의 각 줄은 다음과 같은 결과를 필터링합니다.
- 서브쿼리문의 수가 1인 경우
- 서브쿼리가 101 또는 100인 경우
- 서브쿼리가 01로 끝나는 경우
마지막으로 SELECT COUNT(*) AS `COUNT`를 통해 필터링된 데이터 열의 갯수를 COUNT라는 컬럼명으로 출력하도록 해 주었습니다. 정답 통과입니다.
[2] 비트 연산으로 풀어보기
MySQL에는 비트(Bit) 단위로 논리 연산을 수행하는 연산자가 있습니다. 챗지피티한테 비트 연산자의 종류에 뭐가 있는지 테이블을 만들어 달라고 했는데요.
비트 AND (&) | 비트별 AND 연산을 수행합니다. 두 비트가 모두 1이면 결과는 1이 되고, 그렇지 않으면 결과는 0이 됩니다. |
비트 OR ( | ) | 비트별 OR 연산을 수행합니다. 두 비트 중 하나라도 1이면 결과는 1이 되고, 둘 다 0이면 결과는 0이 됩니다. |
비트 XOR (^) | 비트별 XOR 연산을 수행합니다. 두 비트가 같으면 결과는 0이 되고, 다르면 결과는 1이 됩니다. |
비트 NOT (~) | 비트를 반전시킵니다. 0은 1로, 1은 0으로 변환됩니다. |
비트 왼쪽 시프트 (<<) | 모든 비트를 왼쪽으로 이동시킵니다. 오른쪽에 0으로 채워집니다. |
비트 오른쪽 시프트 (>>) | 모든 비트를 오른쪽으로 이동시킵니다. 왼쪽에 부호 비트와 같은 값으로 채워집니다. |
네. 이런게 있다네요. (^_^;;) 저는 여기서 &연산자와 NOT 연산자를 사용해서 위의 문제를 풀어보겠습니다.
SELECT * FROM ECOLI_DATA
WHERE
GENOTYPE & 5
AND NOT GENOTYPE & 2
GENOTYPE & 5
- 정수 5를 2진법 비트로 변환하면 101입니다. 따라서 &5는 값의 첫 번째, 세 번째 비트가 1인지 여부를 확인합니다.
NOT GENOTYPE & 2
- 비트 NOT 연산은 비트를 반전시키는 역할을 합니다. 여기서 2의 이진 표현은 10입니다. 따라서 이 비트 연산은 GENOTYPE 열의 값에서 2번째 비트를 확인하고, 그 값을 반전시키므로, 2번째 비트가 0인지 여부를 확인합니다.
SELECT COUNT(ID) AS `COUNT`
FROM ECOLI_DATA
WHERE
GENOTYPE & 5
AND NOT GENOTYPE & 2
마지막으로 카운트한 값을 출력해 주면 정답 통과입니다.
비트 연산자는 간단하게 풀 수 있지만 까먹기 쉽다는 단점이 있는 것 같습니다.
그래도 이런 게 있다는 걸 알아두고 필요할 때마다 열심히 꺼내 보면서 익숙해 져야겠습니다.