ECOLI_DATA 테이블에서 특정 개체의 형질을 가지고 있지 않은/가지고 있는 개체의 수를 COUNT
- 2번 형질을 보유하지 않으면서 1번이나 3번 형질을 보유하고 있는 개체의 수 COUNT.
- 1번과 3번 형질을 모두 보유하고 있는 경우, 1번이나 3번을 보유하고 있는 경우 COUNT에 포함.
- 문제에서는 GENOTYPE 값을 2진수로 변환한 뒤 각 자리수를 각 형질로 판단하고 있다.
- 예를 들어, 15인 경우 이진수로 변환하면 1111로 1,2,3,4의 형질을 보유한다.
- 예를 들어, 13인 경우 이진수로 변환하면 1101로 1,3,4의 형질을 보유한다.
- 즉, 4자리수라면 뒷자리에서부터 1,2,3,4 형질로 보고 있다.
WHERE절에서 특정 특질 보유/미보유 여부를 판단할 수 있도록 조건을 부여한다.
- '1번과 3번 형질을 모두 보유하고 있는 경우'와 '1번이나 3번을 보유하고 있는 경우'는 중복된 조건! '1번이나 3번을 보유하는 경우'에 '1번과 3번 형질을 모두 보유하는 경우'가 포함되므로 '1번과 3번 형질을 모두 보유하는 경우'는 고려하지 않는다. - '1번이나 3번을 보유하는 경우'만 고려.
- 각 형질은 각 이진수의 자리수로 판단.
- BIN 함수를 사용하여 GENOTYPE의 값을 이진수로 변환
- 각 자리수에서 두번째 자리가 0이면서, 첫번째나 세번째 자리가 1인 경우의 데이터 COUNT
- 비트 연산자를 사용하여 이진수 & 2 -> 두번째 자리가 1인지 판단.
- 비트 연산자를 사용하여 (이진수 & 1 OR 이진수 & 4) -> 첫번째 자리 혹은 3번째 자리가 1인지 판단.
SELECT COUNT(GENOTYPE) AS COUNT
FROM ECOLI_DATA
WHERE !(BIN(GENOTYPE)&2)
AND (BIN(GENOTYPE)&1 OR BIN(GENOTYPE)&4);
비트 연산자 개념에 대해 공부하고 난뒤 BIN함수가 불필요하다는 것을 알게되었다. 비트 연산자는 사용 시에 연산 대상이 되는 숫자에 대해 자동으로 이진수 변환이 이루어지므로, 현재 쿼리는 BIN함수와 비트 연산자로 이진수 변환이 2번 이루어졌다.
SELECT COUNT(GENOTYPE) AS COUNT FROM ECOLI_DATA WHERE !(GENOTYPE & 2) AND (GENOTYPE & 1 OR GENOTYPE & 4);
이렇게 BIN 함수를 제외한다면 더 간단하고 불필요한 작업이 없는 쿼리가 완성된다!
BIN() --> 괄호 안의 수를 2진법으로 변환
비트(bit) 단위로 논리 연산을 할 때 사용하는 연산자로 연산 대상이 되는 숫자를 이진수로 표현하여 각 비트 단위로 AND, OR 등의 연산을 수행한다. 각 자릿수의 연산은 독립적으로 이루어진다.
- AND 연산(&) : 두 비트가 모두 1일때만 1을 반환한다.
- OR 연산(|) : 두 비트가 하나라도 1이면 1을 반환한다.
- XOR 연산(^) : 두 비트가 다르면 1, 같으면 0을 반환한다.
- NOT 연산(~) : 비트를 반전시킨다.
출처