재밌을 때 진도 쭉쭉 빼기!
자동차 대여 기록에서 장기/단기 대여 구분하기
#DATEDIFF #DATE_FORMAT
와... 쓸데없이 짱 헤멘 문제.
DATEDIFF한 결과값에 +1을 해줘야 한다. 질문하기 게시판에 요 내용으로 틀린 사람들이 수두룩...
왜냐하면 오늘 빌려서 오늘 반납한 경우, 두 날짜를 빼면 0이 되지만 대여일은 1일로 계산하기 때문이다.
마찬가지로 오늘 빌려서 내일 반납하면 대여일은 2일이다.
SELECT history_id,
car_id,
DATE_FORMAT(start_date, '%Y-%m-%d') start_date,
DATE_FORMAT(end_date, '%Y-%m-%d') end_date,
IF (DATEDIFF(END_DATE,START_DATE)+1 >= '30',
'장기 대여', '단기 대여') AS RENT_TYPE
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE DATE_FORMAT(START_DATE, '%Y-%m') = '2022-09'
ORDER
BY HISTORY_ID DESC
특정 옵션이 포함된 자동차 리스트 구하기
#LIKE
SELECT *
FROM CAR_RENTAL_COMPANY_CAR
WHERE OPTIONS LIKE '%네비게이션%'
ORDER
BY CAR_ID DESC
조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기
#CONCAT #JOIN #WHERE
CONCAT을 활용해야 했던 문제. JOIN에 WHERE조건까지 살짝 쫄았지만 침착하게 풀었다.
언제쯤 아 이거 아는데... 함수가 뭐였더라...? 하지 않고 척척 풀 수 있게 될까?
문제풀이 끝내는 3주 뒤에는 그렇게 되길!
SELECT CONCAT('/home/grep/src/',F.BOARD_ID,
'/',F.FILE_ID,F.FILE_NAME,F.FILE_EXT)
FILE_PATH
FROM USED_GOODS_BOARD B
JOIN USED_GOODS_FILE F
ON B.BOARD_ID = F.BOARD_ID
WHERE B.VIEWS =
(SELECT MAX(VIEWS) FROM USED_GOODS_BOARD)
ORDER
BY FILE_ID DESC
;
조건에 맞는 사용자 정보 조회하기
# CONCAT_WS #SUBSTRING #SUBSTR #HAVING
여전히 헷갈리는 WHERE과 HAVING. 일단은 GROUP BY를 사용해 묶어놓은 열에서 조건을 찾고 싶으면 HAVING이라고 생각해본다.
그래도 이렇게 어려운 문제 혼자 풀었을 때의 짜릿함이란!
SELECT U.USER_ID, U.NICKNAME,
CONCAT_WS(' ', CITY, STREET_ADDRESS1, STREET_ADDRESS2) 전체주소,
CONCAT_WS('-',SUBSTR(TLNO,1,3),SUBSTR(TLNO,4,4),SUBSTR(TLNO,8,4)) 전화번호
FROM USED_GOODS_BOARD B
JOIN USED_GOODS_USER U
ON B.WRITER_ID = U.USER_ID
GROUP
BY USER_ID
HAVING COUNT(USER_ID) >= 3
ORDER
BY U.USER_ID DESC
;
자동차 대여 기록 별 대여 금액 구하기
WITH, CASE
⏰ 33:10
휴우 이제 이정도는 뚝딱뚝딱 할 수 있게 되었다!
WITH HISTORY AS (
SELECT HISTORY_ID,
CAR_TYPE,
DATEDIFF(END_DATE, START_DATE) + 1 AS DURATION,
CASE WHEN DATEDIFF(END_DATE, START_DATE) + 1 BETWEEN 7 AND 29 THEN '7일 이상'
WHEN DATEDIFF(END_DATE, START_DATE) + 1 BETWEEN 30 AND 89 THEN '30일 이상'
WHEN DATEDIFF(END_DATE, START_DATE) + 1 >= 90 THEN '90일 이상'
END AS DURATION_TYPE,
START_DATE,END_DATE,
DAILY_FEE
FROM CAR_RENTAL_COMPANY_CAR
JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY
USING (CAR_ID)
WHERE CAR_TYPE = '트럭'
ORDER BY 3
)
SELECT HISTORY_ID, -- H.CAR_TYPE, DAILY_FEE,DURATION, DISCOUNT_RATE, START_DATE, END_DATE,
CASE WHEN DISCOUNT_RATE IS NULL THEN ROUND(DURATION * DAILY_FEE,0)
ELSE ROUND(DURATION * DAILY_FEE * (100 - DISCOUNT_RATE) / 100,0)
END AS FEE
FROM HISTORY H
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN P
ON P.CAR_TYPE = H.CAR_TYPE AND P.DURATION_TYPE = H.DURATION_TYPE
ORDER BY 2 DESC,1 DESC
조건에 부합하는 중고거래 상태 조회하기
#CASE #DATE_FORMAT
이제 CASE 구문도 익숙해지는 중!
SELECT BOARD_ID, WRITER_ID, TITLE, PRICE,
CASE WHEN STATUS = 'SALE'
THEN '판매중'
WHEN STATUS = 'RESERVED'
THEN '예약중'
ELSE '거래완료'
END AS STATUS
FROM USED_GOODS_BOARD
WHERE DATE_FORMAT(CREATED_DATE, '%Y-%m-%d') = '2022-10-05'
ORDER
BY BOARD_ID DESC
;
조건별로 분류하여 주문상태 출력하기
#DATE #CASE
오늘도 어이없는 실수로 한참 고민한 썰 푼다.. (FEAT. 쉼표 빼먹음)
SELECT ORDER_ID, PRODUCT_ID,
DATE_FORMAT(OUT_DATE, '%Y-%m-%d') OUT_DATE,
CASE WHEN DATEDIFF('2022-05-01',OUT_DATE) >= 0
THEN '출고완료'
WHEN DATEDIFF('2022-05-01',OUT_DATE) < 0
THEN '출고대기'
WHEN OUT_DATE IS NULL
THEN '출고미정'
END
출고여부
FROM FOOD_ORDER
ORDER
BY ORDER_ID
;
대여 기록이 존재하는 자동차 리스트 구하기
#JOIN #AND #DISTINCT
SELECT DISTINCT C.CAR_ID
FROM CAR_RENTAL_COMPANY_CAR C
JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY H
ON C.CAR_ID = H.CAR_ID
WHERE CAR_TYPE = '세단' AND MONTH(start_date) = 10
ORDER
BY CAR_ID DESC
;
자동차 평균 대여 기간 구하기
#GROUPBY #HAVING #AVG #ROUND
SELECT CAR_ID, ROUND(AVG(DATEDIFF(END_DATE,START_DATE)+1),1) AVERAGE_DURATION
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP
BY CAR_ID
HAVING AVG(DATEDIFF(END_DATE,START_DATE)+1) >= 7
ORDER
BY AVERAGE_DURATION DESC, CAR_ID DESC
;
취소되지 않은 진료 예약 구하기
JOIN
⏰ 10:10
이제 이정도는 뚝딱인걸로!
SELECT A.APNT_NO,
P.PT_NAME,
P.PT_NO,
A.MCDP_CD,
D.DR_NAME,
A.APNT_YMD
FROM APPOINTMENT A
LEFT JOIN PATIENT P
ON A.PT_NO = P.PT_NO
LEFT JOIN DOCTOR D
ON A.MDDR_ID = D.DR_ID
WHERE A.APNT_CNCL_YN = 'N'
AND A.MCDP_CD = 'CS'
AND DATE_FORMAT(A.APNT_YMD, '%Y-%m-%d') = '2022-04-13'
ORDER BY A.APNT_YMD
루시와 엘라 찾기
#IN #WHERE
처음에 IN 함수에 따옴표 ' 안 붙여서 오류가 떴고... 한참 헤멜 뻔 했다!
복잡함에 속아 기본을 잊지 말자(?)
SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
WHERE NAME IN ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty')
ORDER
BY ANIMAL_ID
;
이름에 el이 들어가는 동물 찾기
#LIKE #AND
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE NAME LIKE '%EL%' AND ANIMAL_TYPE = 'DOG'
ORDER
BY NAME
;
중성화 여부 파악하기
#CASE
지난번에 풀었던 CASE 구문이다! 하고 신나게 풀었다가 END 안써서 틀린 사람~ 그게 나예요~
차차 기본적인 실수는 줄여나가자.
SELECT ANIMAL_ID, NAME,
CASE WHEN SEX_UPON_INTAKE LIKE 'Neutered%'
THEN 'O'
WHEN SEX_UPON_INTAKE LIKE 'Spayed%'
THEN 'O'
ELSE 'X'
END 중성화
FROM ANIMAL_INS
ORDER
BY ANIMAL_ID
;
오랜 기간 보호한 동물(2)
#JOIN #LIMIT
서브쿼리와 RANK를 써야하나..? 한참 끙끙 앓다가 챗GPT한테도 물어보고 이것저것 시도해보는데 1시간을 썼다.
LIMIT을 쓰면 뚝딱이고, ORDER BY에서는 굳이 SELECT에서 안 뽑는 열을 써도 되는데 괜히 JOIN이라고 쫄아서 생각 못하고 있었던 것...
SELECT I.ANIMAL_ID, I.NAME
FROM ANIMAL_INS I
JOIN ANIMAL_OUTS O
ON I.ANIMAL_ID = O.ANIMAL_ID
ORDER
BY DATEDIFF(O.DATETIME, I.DATETIME) DESC
LIMIT 2
;
DATETIME에서 DATE로 형 변환
#DATE_FORMAT
첫 날만 해도 이걸 어케 외우지..? 했는데 그새 뚝딱! 반복 연습이 답이다.
SELECT ANIMAL_ID, NAME, DATE_FORMAT(DATETIME,'%Y-%m-%d') 날짜
FROM ANIMAL_INS
ORDER
BY ANIMAL_ID
;
카테고리 별 상품 개수 구하기
#COUNT #LEFT #GROUPBY
SELECT CATEGORY, COUNT(1) PRODUCTS
FROM (SELECT *, LEFT(PRODUCT_CODE,2) CATEGORY
FROM PRODUCT) P
GROUP
BY CATEGORY
ORDER
BY CATEGORY
;
와아. 이번 분류는 양이 꽤 많았다. 내일 일이 있어 내일 진도 분량까지 다 해버렸더니... 거의 3시간이 걸렸다!
놀라운 사실은 그동안 엉덩이 한 번 안 떼고 몰입했다는 것... 이거 왜 재밌지...?(어리둥절)
'[공부] SQL' 카테고리의 다른 글
[SQL 코딩테스트] 리트코드 Basic Joins 정답 (0) | 2024.01.22 |
---|---|
[SQL 코딩테스트] 리트코드 Select 정답 (0) | 2024.01.22 |
[SQL 코딩테스트] 프로그래머스 IS NULL 정답 (0) | 2024.01.17 |
[SQL 코딩테스트] 프로그래머스 SUM, MAX, MIN 정답 (0) | 2024.01.17 |
[SQL 코딩테스트] 프로그래머스 SELECT 정답 (2) (0) | 2024.01.16 |