Notice
Recent Posts
Recent Comments
«   2024/11   »
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
Tags
more
Archives
Today
Total
관리 메뉴

No Limitation

[SQL] 주의해야 할 유형 본문

프로그래밍

[SQL] 주의해야 할 유형

yesungcho 2024. 3. 21. 14:42

SQL 코테 시 주의해야 하는 유형들

1. WHERE 다중 조건문 수행 시
https://www.hackerrank.com/challenges/what-type-of-triangle/problem

 

Type of Triangle | HackerRank

Query a triangle's type based on its side lengths.

www.hackerrank.com

 

위 문제에서 중요한 특징은 "이전 WHERE 조건에서 필터된 경우 다음 WHERE 조건에는 반영되지 않는다"는 점.

예를 들어 아래 코드를 보면

SELECT CASE 
           -- 정삼각형 조건
           WHEN A=B AND B=C THEN 'Equilateral' 
           -- 삼각형 여부 판단 
           -- 정삼각형은 무조건 삼각형이 성립, 하지만 이등변의 경우 삼각형이 성립하지 않을 수 있음
           -- 따라서 본 조건이 먼저 등장
           WHEN A+B<=C OR A+C<=B OR B+C<=A THEN 'Not A Triangle'
           -- 이등변 삼각형 조건
           -- 정삼각형도 이등변이지만, 이미 첫번째 WHERE에서 filter되서 두번째에서는 고려 X
           WHEN A=B OR B=C OR C=A THEN 'Isosceles'
           -- 이 외의 케이스
           WHEN A<>B AND B<>C AND C<>A THEN 'Scalene'
       END
FROM Triangles

 

주석이 좀 많은데 중요한 점이 조건의 순차가 앞에서부터 가장 엄격한 조건이 들어간다.

이걸 조금 더 이해를 돕기 위해 그림을 그려 보면

일단 세개의 변이 모두 같으면 무조건 삼각형이다. 즉, 빨간색은 가장 엄격한 조건이 된다.
그 다음으로는 조건이 '이등변', '삼각형유무', '세 변 상이' 인데
여기서 삼각형인지 아닌지의 조건이 '이등변' 부분보다 더 엄격한 조건이 되므로 (빨간색 기준)
삼각형 유무를 판단하는 'Not a Triangular' 조건
그 다음에 이등변 조건이 들어오게 된다. 

이렇게 조건에 따른 순서를 구축하는 것이 본 문제의 핵심이다.

두 번째로는 서브 쿼리에 익숙해지는 것인데
https://school.programmers.co.kr/learn/courses/30/lessons/151139?language=mysql

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

요 문제에서는 

-- 이 문제는 서브쿼리를 적절히 사용하는 방법임
SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(*) AS RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE CAR_ID IN (
    SELECT CAR_ID
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
	-- 여기서의 조건은 그저 ID 필터링 정도로...!
    WHERE DATE_FORMAT(START_DATE,'%Y-%m') BETWEEN '2022-08' AND '2022-10' 
    GROUP BY CAR_ID
    HAVING COUNT(*) >= 5) AND	
    -- 여기서는 다시 기간을 반영하기 위함!
    -- 위에서 ID를 뽑았다고 메인 쿼리에서 기간이 반영되는 것은 아님!
    DATE_FORMAT(START_DATE,'%Y-%m') BETWEEN '2022-08' AND '2022-10' 
GROUP BY MONTH, CAR_ID
HAVING RECORDS>0
ORDER BY MONTH, CAR_ID DESC

 

세 번째 WHERE 명령어 이후, 또 SELECT 가 들어가는 서브 쿼리 부분에 주목해보자
우선 서브 쿼리의 SELECT에서 우리가 원하는 1차 조건에 해당하는 부분을 필터링하고
두 번째 SELECT에서 메인 task를 수행한다.

이 때 주의해야 할 점은 메인 쿼리에서도 동일하게 날짜에 대한 조건이 들어가는데
왜냐하면 서브 쿼리 때 수행한 날짜의 조건의 output은 해당하는 id만 내놓지만
다시 메인 쿼리를 수행할 때는 그냥 id만 고려하지, 날짜에 대한 필터 정보는 알지 못하는 상황이다.

따라서 이를 다시 가이드하는 조건을 추가하는 명령어가 필요하다

또 추가 서브 쿼리를 사용하는 문제에서 주의해야 할 유형
https://school.programmers.co.kr/learn/courses/30/lessons/131123?language=mysql

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

이 유형도 중요하다... 그냥 생각 없이 group by로 한다음에 select 했다가 key가 맞지 않는 문제를 대응하기 위해
group by로 계산한 음식의 종류와 max 값을 서브 쿼리에서 반환하여 이를 메인 쿼리에서 추출하는 방식으로 구현해야 한다.

아래 분께서 포스팅으로 잘 정리해 놓으셨다.
https://coduking.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-SQL-%EC%A6%90%EA%B2%A8%EC%B0%BE%EA%B8%B0%EA%B0%80-%EA%B0%80%EC%9E%A5-%EB%A7%8E%EC%9D%80-%EC%8B%9D%EB%8B%B9-%EC%A0%95%EB%B3%B4-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0

 

[프로그래머스 SQL] 즐겨찾기가 가장 많은 식당 정보 출력하기

정답코드 SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES FROM rest_info WHERE (food_type, favorites) IN (SELECT food_type, max(favorites) FROM REST_INFO GROUP BY FOOD_TYPE) ORDER BY food_type desc; 설명 아마도 이 글을 클릭 한 사람이라면

coduking.com

-- 코드를 입력하세요
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES 
FROM REST_INFO
WHERE (FOOD_TYPE, FAVORITES) IN (
    SELECT FOOD_TYPE, MAX(FAVORITES) -- 음식 종류별로 즐겨찾기 수가 가장 많은! 
    FROM REST_INFO
    GROUP BY FOOD_TYPE
    )
ORDER BY FOOD_TYPE DESC