세조목

TIL(Today I Learned)6일차(23.12.05) 본문

데이터 분석 공부/TIL(Today I Learned)

TIL(Today I Learned)6일차(23.12.05)

세조목 2023. 12. 5. 21:28

1. SQL

 1) 프로그래머스 30번 문제

https://school.programmers.co.kr/learn/courses/30/lessons/151137

프로그래머스

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

programmers.co.kr

Q. CAR_RENTAL_COMPANY_CAR 테이블에서 '통풍시트', '열선시트', '가죽시트' 중 하나 이상의 옵션이 포함된 자동차가 자동차 종류 별로 몇 대인지 출력하는 SQL문을 작성해주세요. 이때 자동차 수에 대한 컬럼명은 CARS로 지정하고, 결과는 자동차 종류를 기준으로 오름차순 정렬해주세요.
 
문제는 위와같았다.
처음에는 where options like in ('%통풍시트%', '%열선시트%', '%가죽시트%') 이렇게 작성했는데 정답 처리가 되지 않았다. 무엇이 문제인고 확인해보니 in ('%통풍시트%', '%열선시트%', '%가죽시트%') 라고 코드를 작성하는 것이 아니라
where options like '%통풍시트%' or options like '%열선시트%' or options like '%가죽시트%' 라고 작성해야하는 것이였다.
like를 사용하면서 여러개 조건을 지정하고싶을때는  in ( )을 쓰는게 아니라 or를 쓰자

 

 2) 프로그래머스 31번 문제

https://school.programmers.co.kr/learn/courses/30/lessons/59044

프로그래머스

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

programmers.co.kr

Q. 아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일 순으로 조회해야 합니다.
 
입양을 못 간 동물들을 어떻게 확인할 수 있을까??
우선 이 문제에서는 두 개의 테이블을 제공한다.
그 두가지는 시설에 들어온 동물들의 데이터가 정리된 테이블(이하 A)입양보낸 동물들의 데이터가 정리된 테이블(이하 B)이다.
입양을 간 녀석들은 A와 B 두 테이블에 모두 들어있을 것이다.
반대로 입양가지 못한 녀석들은 B 테이블에는 데이터가 존재하지 않을 것이다.
그렇다면 A와 B 테이블을 left join 하면 어떤 녀석이 입양가지 못했는지 한눈에 확인할 수 있을 것이다.
왜??
left join은 두 테이블 중에서 한 곳에서라도 데이터가 있으면 표시되기 때문이다.
다시 말해 B에는 데이터가 없어도 A에는 데이터가 있기때문에 join된 테이블에 표시가 된다.
 

3) 프로그래머스 32번 문제

https://school.programmers.co.kr/learn/courses/30/lessons/144855

프로그래머스

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

programmers.co.kr

(좌) 수정 전 코드 / (우) 수정 후 코드

 
Q. 2022년 1월 카테고리 별 도서 판매량을 합산하고, 카테고리(CATEGORY), 총 판매량(TOTAL_SALES) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 카테고리명을 기준으로 오름차순 정렬해주세요.
 
문제에서는 2022년 1월의 카테고리 별 데이터들을 요구하고 있다.
어떻게 구할 수 있을까??
조건이니까 WHERE절을 사용했다.
SALES_DATE 열에 01이 포함된 값을 가져오면 되겠지싶어서 '%01%'를 입력했는데 정답이 아니었다.
왜 정답이 아닐까 생각해보니 01은 월(月) 뿐만 아니라 일(日)에도 있었다.
그렇다보니 합해지는 SALES의 양이 커질수밖에 없던 것이다.
코드를 '%2022-01%'로 수정하니 정답인 것을 확인할 수 있었다.
 

 4) 프로그래머스 35번 문제

https://school.programmers.co.kr/learn/courses/30/lessons/59411

프로그래머스

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

programmers.co.kr

<DATEDIFF함수 사용 X>

SELECT I.ANIMAL_ID,
       I.NAME
FROM ANIMAL_INS I INNER JOIN ANIMAL_OUTS O ON I.ANIMAL_ID = O.ANIMAL_ID
ORDER BY DATE(O.DATETIME)-DATE(I.DATETIME) DESC
LIMIT 2

 
<DATEDIFF함수 사용 O>

SELECT I.ANIMAL_ID,
       I.NAME,
       DATEDIFF(O.DATETIME, I.DATETIME)
FROM ANIMAL_INS I INNER JOIN ANIMAL_OUTS O ON I.ANIMAL_ID = O.ANIMAL_ID
ORDER BY DATEDIFF(O.DATETIME, I.DATETIME) DESC
LIMIT 2

 
이번 문제는 정답을 맞추긴 했지만 일(日)의 차이를 보니 값이 이상해서 무엇이 잘못되었는지 고민해봤다.
내가 작성한것처럼 DATE(O.DATETIME) - DATE(I.DATETIME)을 하게되면 아래와 같이 9,983, 9,788이라는 숫자가 나온다.

 
기간의 차이가 1년을 넘기지 않을텐데 저런 값이 나온다는건 내가 코드를 잘못 작성했다는 말이다.
그런데 아무리 고민해봐도 무엇이 잘못 됐는지 모르겠어서 다른 사람들이 올린 코드를 확인해보니
내가 모르는 함수를 활용해서 문제를 풀고 있었다.
 
그 함수가 바로 DATEDIFF함수이다.
 
DATEDIFF함수는 날짜 시간 차이를 알려주는 함수라고한다.
날짜 뿐만 아니라 년도, 시간, 주의 차이도 구할 수 있다고한다.
인자 구성도 간단하다.
DATEDIFF('구분자', '시작날짜시간', '종료날짜시간') 이다.

 구분자약어
년도yearyy, yyyy
분기quarterqq, q
monthmm, m
daydd, d
weekwk
시간hourhh
minutemi, n
secondss, s
밀리초millisecondms
마이크로초microsecondmcs
나노초nanosecondns

 
DATEDIFF 함수를 활용하여 코드를 작성하게 되면 ORDER BY 절에 다음과 같이 코드가 들어가게된다.
 
ORDER BY DATEDIFF(O.DATETIME, I.DATETIME) DESC

 
여기서 한가지 짚고 넘어가야하는 것이 있는데 앞서 DATEDIFF함수의 인자는 다음과 같다고 했다.
DATEDIFF('구분자', '시작날짜시간', '종료날짜시간') 
그러나 위에서 우리는 DATEDIFF(O.DATETIME, I.DATETIME) 라고 코드를 작성했다.
O.DATETIME이 종료 날짜, I.DATETIME이 시작날짜인데 설명과 다르지 않은가?
 
나의 추측이긴한데 본 문제에서 DATEDIFF함수를 쓸때는 구분자를 별도로 사용하지 않았다.
이처럼 구분자를 사용하지 않을때는 종료날짜와 시작날짜의 순서가 바뀌는 것 아닐까??