[MySQL- Lv.2] -TRUNCATE, HOUR, CASE

박경희·2024년 1월 1일

코딩테스트

목록 보기
14/69

문제1 - 상품 별 오프라인 매출 구하기

SELECT P.PRODUCT_CODE, SUM(O.SALES_AMOUNT * P.PRICE) AS SALES
FROM PRODUCT P
JOIN OFFLINE_SALE O ON P.PRODUCT_ID = O.PRODUCT_ID
GROUP BY P.PRODUCT_CODE
ORDER BY 2 DESC, 1
  • on절 빼먹지 말기
  • select에서 sum을 해줘야 group by 했을 때 코드별 합계로 계산된다.

문제2 - 조건에 맞는 도서와 저자 리스트 출력하기

SELECT BOOK_ID, AUTHOR_NAME, DATE_FORMAT(PUBLISHED_DATE, '%Y-%m-%d') as PUBLISHED_DATE
FROM BOOK B JOIN AUTHOR A ON B.AUTHOR_ID = A.AUTHOR_ID
WHERE B.CATEGORY = '경제'
ORDER BY PUBLISHED_DATE
  • 항상 주의사항까지 꼼꼼히 보며 문제 풀자.

문제3 - 3월에 태어난 여성 회원 목록 출력하기

SELECT MEMBER_ID, 
    MEMBER_NAME, 
    GENDER, DATE_FORMAT(DATE_OF_BIRTH, '%Y-%m-%d') as DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE TLNO IS NOT NULL AND DATE_OF_BIRTH LIKE '%03%' AND GENDER = 'W'
ORDER BY MEMBER_ID;
  • 여러 조건을 꼼꼼히 체크하며 작성하자~!
WHERE MONTH(DATE_OF_BIRTH) = 3
  • 이런 방법으로도 3월을 찾을 수 있다.

문제4 - 가격대 별 상품 개수 구하기

CASE

SELECT 
    CASE 
    WHEN PRICE < 10000 THEN '0'
    WHEN PRICE >= 10000 AND PRICE < 20000 THEN '10000'
    WHEN PRICE >= 20000 AND PRICE < 30000 THEN '20000'
    WHEN PRICE >= 30000 AND PRICE < 40000 THEN '30000'
    ELSE '40000만원 이상'
    END AS PRICE_GROUP
, COUNT(PRODUCT_ID) AS PRODUCTS
FROM PRODUCT
GROUP BY 1
ORDER BY 1
  • case를 사용하려다 보니 '가격대가 계속 있으면 계속 이걸 만들어줘야 하나?'라는 의문이 들었고 그래서
    우선 예시에 나온 가격대 까지만 처리를 했다.
  • 다른 방법은 없을까 하고 찾아보니 TRUNCATE를 사용하는 방법이 있었다.

TRUNCATE : 특정 자릿수에서 자르는 함수

SELECT 
	TRUNCATE(PRICE, -4) AS PRICE_GROUP, 
	COUNT(PRODUCT_ID) AS PRODUCTS
FROM PRODUCT
GROUP BY 1
ORDER BY 1
  • MySQL의 TRUNCATE 함수는 주어진 숫자를 지정된 소수점 자릿수까지 자르는데, 음수를 사용하면 소수점이 아닌 자릿수를 기준으로 값을 자른다.

  • 예를 들어, PRICE가 15000인 경우 TRUNCATE(PRICE, -4)는 10000을 반환하고, 25000인 경우에는 20000을 반환한다. 이렇게 해서 가격대별로 상품을 그룹화하고, COUNT(*)를 사용하여 각 가격대별 상품의 수를 세어 PRODUCTS 열에 저장한다.

  • 이 방법을 사용하니 case를 사용하며 생겼던 의문과 문제점이 바로 해결됐다.


문제5 - 입양 시각 구하기(1)

처음 작성한 쿼리

SELECT DATE_FORMAT(DATETIME, '%H') AS HOUR, COUNT(ANIMAL_ID) AS COUNT
FROM ANIMAL_OUTS
WHERE DATE_FORMAT(DATETIME, '%H') > '08'
GROUP BY 1
ORDER BY 1

  • 정답 예시와 완전히 일치해 보였는데도 오답으로 처리되서 다시 비교해보니
    9시 표기를 '09'가 아니라 '9'로 나오도록 처리해야 했다.
SELECT DATE_FORMAT(DATETIME, '%k') AS HOUR, COUNT(ANIMAL_ID) AS COUNT
FROM ANIMAL_OUTS
WHERE CAST(DATE_FORMAT(DATETIME, '%k') AS UNSIGNED) > 8
GROUP BY HOUR
ORDER BY CAST(HOUR AS UNSIGNED);
  • MySQL에서 시간을 09 대신 9와 같이 앞에 0을 포함하지 않는 형식으로 표시하기 위해 %k 포맷 지정자를 사용했지만 %k 는 시간을 표시하기 때문에 원하는대로 정렬되지 않았다.

  • 원하는 정렬로 나올 수 있도록 CAST 함수를 사용하여 문자열을 숫자로 변환한 후 > 8로 비교했고
    ORDER BY로 정렬하니 결과적으론 예시와 똑같은 정답이 출력됐다.

  • 그러나 결과적으로 정답 처리가 되지 않았다. 원하는 형식이 이게 아닌듯 하여 다른 방법을 찾아봤다.

HOUR 함수

SELECT HOUR(DATETIME) AS HOUR, COUNT(ANIMAL_ID) AS COUNT
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) BETWEEN '9' AND '19'
GROUP BY 1
ORDER BY 1;
  • 단순하게 HOUR 함수를 사용하여 아주 간단하게 해결할 수 있는 문제였다.
  • HOUR 함수는 날짜 및 시간 값에서 시간(hour) 부분을 추출하는 데 사용한다.

  • HOUR 함수DATETIME, TIME, 또는 TIMESTAMP 타입의 값을 받아 시간의
    hour 부분(0에서 23 사이의 값)을 정수로 반환한다.

0개의 댓글