https://school.programmers.co.kr/learn/courses/30/parts/17044
여기 문제 참고했습니다 ^__^
[문제]
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 대여 시작일을 기준으로 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서 해당 기간 동안의 월별 자동차 ID 별 총 대여 횟수(컬럼명: RECORDS) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 월을 기준으로 오름차순 정렬하고, 월이 같다면 자동차 ID를 기준으로 내림차순 정렬해주세요. 특정 월의 총 대여 횟수가 0인 경우에는 결과에서 제외해주세요.
📌 날짜 비교 시 > TO_CHAR이 아닌 TO_DATE를 사용한다
TO_DATE("날짜","형식)
예) TO_DATE("2020-02-05","YYYY-MM-DD")
📌 BETWEEN 사용 시 > 컬럼명 BETWEEN 값 AND 값
START_DATE BETWEEN 비교1 AND 비교2
[정답]
SELECT TO_NUMBER(TO_CHAR(START_DATE, 'MM')) AS MONTH
, CAR_ID
, COUNT(CAR_ID) AS RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE CAR_ID IN ( -- CAR_ID를 조건을 걸어야 함 (기간 및 횟수)
SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE TO_CHAR(START_DATE,'YYYYMM') BETWEEN '202208' AND '202210'
GROUP BY CAR_ID
HAVING COUNT(CAR_ID) > 4
) AND TO_CHAR(START_DATE,'YYYYMM') BETWEEN '202208' AND '202210'
GROUP BY TO_CHAR(START_DATE, 'MM'), CAR_ID
HAVING COUNT(CAR_ID) > 0
ORDER BY TO_CHAR(START_DATE, 'MM'), CAR_ID DESC;
[문제]
2022년 1월의 도서 판매 데이터를 기준으로 저자 별, 카테고리 별 매출액(TOTAL_SALES = 판매량 * 판매가) 을 구하여, 저자 ID(AUTHOR_ID), 저자명(AUTHOR_NAME), 카테고리(CATEGORY), 매출액(SALES) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 저자 ID를 오름차순으로, 저자 ID가 같다면 카테고리를 내림차순 정렬해주세요.
[정답]
SELECT B.AUTHOR_ID
, A.AUTHOR_NAME
, B.CATEGORY
, SUM(BS.SALES * B.PRICE) AS TOTAL_SALES
FROM BOOK B
JOIN AUTHOR A ON B.AUTHOR_ID = A.AUTHOR_ID
JOIN BOOK_SALES BS ON B.BOOK_ID = BS.BOOK_ID
WHERE TO_CHAR(SALES_DATE,'YYYYMM') LIKE '202201%'
GROUP BY A.AUTHOR_ID, A.AUTHOR_NAME, B.CATEGORY
ORDER BY A.AUTHOR_ID, B.CATEGORY DESC;
여기서 틀린 게 뭐게요 놀랍게도 SELECT에선 B.AUTHOR_ID를 사용하고 GROUP BY에선 A.AUTHOR_ID를 사용해서 틀림 .. 이것도 맞춰줘야 하는 구나..
[문제]
FOOD_PRODUCT 테이블에서 식품분류별로 가격이 제일 비싼 식품의 분류, 가격, 이름을 조회하는 SQL문을 작성해주세요. 이때 식품분류가 '과자', '국', '김치', '식용유'인 경우만 출력시켜 주시고 결과는 식품 가격을 기준으로 내림차순 정렬해주세요.
📌 제품별로 가장 비싼 가격을 구해야 하니까 MAX를 사용할 수 없음 -> 서브쿼리 필요
난 뭔가 서브쿼리에 대한 이해가 부족한 것 같다...
만약 서브쿼리를 사용하지 않고, MAX를 구한다면 식용유가 4개 나온다.
서브쿼리를 사용한다면 각 카테고리별로 가장 비싼 제품의 정보를 명확히 추출할 수 있어서 가장 비싼 가격의 식용유 1개만 추출할 수 있다
즉 서브쿼리에서 카테고리별 최대 가격을 구하고, 이를 원본 테이블과 조인하여 해당 가격을 가진 제품명만 가져올 수 있다.
또 하나의 궁금한 점
FROM에서 사용하는 거랑 WHERE에서 사용하는 거의 차이점을 뭘까?
🍥 FROM의 경우
목적 : 서브쿼리 결과를 테이블처럼 다룰 수 있습니다. 이 경우 서브쿼리는 임시 테이블로 간주되어 외부 쿼리에서 사용할 수 있습니다.
구조 : 이 방식을 사용하면 복잡한 계산이나 집계 결과를 미리 계산하여, 이후의 메인 쿼리에서 이를 조작하거나 필터링할 수 있습니다.
🍥 WHERE의 경우
목적 : 주 쿼리의 조건을 필터링하기 위해 사용합니다. 서브쿼리 결과를 조건으로 사용하여 특정 행을 선택하는 방식입니다.
구조 : 이 방식은 서브쿼리가 특정 조건을 만족하는지 확인하는 데 초점을 맞춥니다
[정답]
SELECT FP.CATEGORY
, FP.PRICE
, FP.PRODUCT_NAME
FROM FOOD_PRODUCT FP
JOIN (
SELECT CATEGORY
, MAX(PRICE) AS MAX_PRICE
-- , PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE CATEGORY IN ('과자', '국', '김치', '식용유')
GROUP BY CATEGORY -- PRODUCT_NAME까지 그룹화해서 여러개 나옴
) SFP ON FP.CATEGORY = SFP.CATEGORY -- JOIN 절에서 AS 사용할 필요 없다.
WHERE FP.PRICE = SFP.MAX_PRICE;
[문제]
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 2022년 10월 16일에 대여 중인 자동차인 경우 '대여중' 이라고 표시하고, 대여 중이지 않은 자동차인 경우 '대여 가능'을 표시하는 컬럼(컬럼명: AVAILABILITY)을 추가하여 자동차 ID와 AVAILABILITY 리스트를 출력하는 SQL문을 작성해주세요. 이때 반납 날짜가 2022년 10월 16일인 경우에도 '대여중'으로 표시해주시고 결과는 자동차 ID를 기준으로 내림차순 정렬해주세요.
📝 진짜 고민됐던 건 그거임 .. 이게 데이터가 600개 있는데 DISTINCT로 뽑아야 할 건 알겠는데 END_DATE가 MAX인 걸 뽑는 게 맞나..? 이게 고민이였어 ㅠ
걍 SQL이랑 달랐던 비밀을 말해 보겟음
💡 별칭 입력 시, 보통 ''를 사용하지만 공백이 포함되면 반드시 "" 사용
[문제]
USED_GOODS_BOARD와 USED_GOODS_USER 테이블에서 완료된 중고 거래의 총금액이 70만 원 이상인 사람의 회원 ID, 닉네임, 총거래금액을 조회하는 SQL문을 작성해주세요. 결과는 총거래금액을 기준으로 오름차순 정렬해주세요.
📝 고민인 게 그거임.. 총거래금액을 구할 때 서브쿼리를 사용해서 해야 할 것 같은데 SELECT에서 해야 할지 WHERE에서 해야 할지..
-> 바보인가.. 그룹화된 값을 사용하고 싶으면 HAVING을 사용하면 됨
-- 완료된 중고 거래의 총금액이 70만 원 이상인 사람의 회원 ID, 닉네임, 총거래금액을 조회
-- 총거래금액을 기준으로 오름차순
SELECT USER_ID
, NICKNAME
, SUM(PRICE) AS TOTAL_SALES
FROM USED_GOODS_BOARD B
JOIN USED_GOODS_USER U ON B.WRITER_ID = U.USER_ID
WHERE STATUS = 'DONE'
GROUP BY USER_ID, NICKNAME
HAVING SUM(PRICE) >= 700000
ORDER BY TOTAL_SALES
움... 서브쿼리 써야 하는 건가
SELECT P.ID
, P.NAME
, P.HOST_ID
FROM PLACES P
JOIN ( -- 여러개인 거 추출해서 그 HOST_ID 거만 추출해서 뽑아내기!
SELECT HOST_ID
FROM PLACES
GROUP BY HOST_ID
HAVING COUNT(*) > 1
) SP ON P.HOST_ID = SP.HOST_ID
WHERE P.HOST_ID = SP.HOST_ID;