-
[프로그래머스] 특정 형질을 가지는 대장균 찾기 MYSQL SQL코딩테스트 준비/SQL 2024. 10. 3. 21:21
https://school.programmers.co.kr/learn/courses/30/lessons/301646
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제
2번 형질이 보유하지 않으면서 1번이나 3번 형질을 보유하고 있는 대장균 개체의 수(COUNT)를 출력하는 SQL 문을 작성해주세요. 1번과 3번 형질을 모두 보유하고 있는 경우도 1번이나 3번 형질을 보유하고 있는 경우에 포함합니다.
풀이1
문제는 GENOTYPE 칼럼의 수를 이진수로 표현했을 때 자릿수에 따라 형질을 가지고 있다고 정의하였다.
D = GENOTYPE_4 * 2^3 + GENOTYPE_3 * 2^2 + GENOTYPE_2* 2^1 + GENOTYPE_1 * 2^0 로 표현 시,
2번 형질이 보유하지 않으면서 1번이나 3번 형질을 보유하고 있는 대장균 개체의 수를 구해야 함으로
(GENOTYPE_2 = 0) AND (GENOTYPE_1 = 1 OR GENOTYPE_3 = 1)인 조건의 검색 개수를 구하면 된다.
구하는 방법은 %(나머지 연산)을 통하여 자릿수 값을 구하고 계산한 결과값은 FLOOR(GENOTYPE/2)을 하여 다음 자릿수를 구하기 위해 사용한다.
SELECT COUNT(*) COUNT FROM (SELECT GENOTYPE%2 GENOTYPE_4, GENOTYPE_3, GENOTYPE_2, GENOTYPE_1 FROM (SELECT FLOOR(GENOTYPE/2) GENOTYPE, GENOTYPE%2 GENOTYPE_3, GENOTYPE_2, GENOTYPE_1 FROM (SELECT FLOOR(GENOTYPE/2) GENOTYPE, GENOTYPE%2 GENOTYPE_2, GENOTYPE_1 FROM (SELECT FLOOR(GENOTYPE/2) GENOTYPE, GENOTYPE%2 GENOTYPE_1 FROM ECOLI_DATA) A) B) C) D WHERE GENOTYPE_2 = 0 AND (GENOTYPE_3 =1 OR GENOTYPE_1 = 1)
COUNT(*) 대신 *로 검색한 결과
풀이2
풀이1로 풀었을 경우에는 네자릿수 밖에 못구한다는 한계도 있고 보기도 복잡하다. SQL에서는 BIN()함수를 통해 바로 이진수를 구할 수 있다. 다만, 이번 문제에서는 네자릿수가 나와야 하는데 BIN() 함수 사용시에는 네자릿수가 나온다는 보장이 없기 때문에, 네자릿수가 아니라면 패딩(0)을 붙여주고 쉽게 이진수를 구한다.
SELECT COUNT(*) COUNT FROM (SELECT RIGHT(BIN(GENOTYPE),4) -- 이진수 뒤의 4자리 GENOTYPE FROM ECOLI_DATA) A WHERE SUBSTRING(LPAD(A.GENOTYPE,4,'0'),-2,1) = '0' -- 이진수 두번째 자리 AND (SUBSTRING(LPAD(A.GENOTYPE,4,'0'),-3,1) = '1' -- 이진수 세번째 자리 OR SUBSTRING(LPAD(A.GENOTYPE,4,'0'),-1,1) = '1') -- 이진수 첫번째 자리
※ LPAD에 길이를 4를 주게 되면 앞에서부터 4를 가지고 오기 때문에 RIGHT로 뒤에 4자리를 들고 와야함
풀이3
이 문제를 보았을 때 가장 쉽게 풀 수 있는 방법은 비트 연산을 하는 것이다.
예를 들어, 이진수 두번째 자리가 0인지 확인하고 싶다면 &2(=> 10(2진수)을 AND 연산) 했을때, 두번째 자리가 1이라면 AND 연산시 2(=10(2진수))이 나올 것이다. 이와 같은 방법으로 세번째 자리, 첫번째 자리가 1인지도 확인할 수 있다.
SELECT COUNT(*) COUNT FROM ECOLI_DATA WHERE GENOTYPE & 2 <> 2 AND (GENOTYPE & 1 = 1 OR GENOTYPE & 4 = 4)
'코딩테스트 준비 > SQL' 카테고리의 다른 글
[프로그래머스] 오프라인/온라인 판매 데이터 통합하기 Oracle (1) 2024.10.09 [프로그래머스] 상위 n개 레코드 ORACLE SQL (0) 2024.10.07 [프로그래머스] 서울에 위치한 식당 목록 출력하기 ORACLE (4) 2024.10.06 [프로그래머스] 강원도에 위치한 생산공장 목록 출력하기 (2) 2024.10.06 [프로그래머스] 재구매가 일어난 상품과 회원 리스트 구하기 ORACLE SQL (0) 2024.10.01