프로그래머스 SQL 풀이 오답노트(6): 날짜 연산, 정렬

SeongGyun Hong·2025년 1월 7일

SQL

목록 보기
30/51

아... 문자정렬 숫자정렬을 까먹어서 20분을 헤맸다;;

1. 필요 이론

SQL에서의 ORDER BY

ORDER BY는 SQL 쿼리 결과를 정렬하는 데 사용되는 절. 하나 이상의 열을 기준으로 데이터를 오름차순(기본값) 또는 내림차순으로 정렬 가능

숫자 정렬 vs 문자열 정렬

  • 숫자 정렬: 숫자 값은 실제 크기 순으로 정렬. 예: 7.0과 7.1은 숫자 정렬 시 7.0이 먼저 나옴
  • 문자열 정렬: 숫자가 문자열로 변환되면 각 문자 단위로 정렬. 예: "7.0"과 "7.1"을 문자열로 정렬하면 "7.0"이 "7.1"보다 먼저 나옴

2. 쿼리 분석

첫 번째 쿼리

SELECT CAR_ID, TO_CHAR(ROUND(AVG(RENT_DURATION), 1), 'FM999.0') AS AVERAGE_DURATION
FROM (
    SELECT HISTORY_ID, CAR_ID, (END_DATE - START_DATE + 1) AS RENT_DURATION
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
)
GROUP BY CAR_ID
HAVING ROUND(AVG(RENT_DURATION), 1) >= 7
ORDER BY AVERAGE_DURATION DESC, CAR_ID DESC;
  • 핵심 개념: TO_CHAR로 변환된 ROUND(AVG(RENT_DURATION), 1) 값이 문자열로 정렬. 문자열 정렬은 숫자와 다르게 각 문자를 기준으로 정렬
  • 예시: "7.0", "7.1", "10.0"이 있다면, 문자열 정렬 결과는 "7.0", "7.1", "10.0" 순으로 정렬

두 번째 쿼리

SELECT CAR_ID, TO_CHAR(ROUND(AVG(RENT_DURATION), 1), 'FM999.0') AS AVERAGE_DURATION
FROM (
    SELECT HISTORY_ID, CAR_ID, (END_DATE - START_DATE + 1) AS RENT_DURATION
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
)
GROUP BY CAR_ID
HAVING ROUND(AVG(RENT_DURATION), 1) >= 7
ORDER BY ROUND(AVG(RENT_DURATION), 1) DESC, CAR_ID DESC;
  • 핵심 개념: ROUND(AVG(RENT_DURATION), 1)의 숫자 값을 기준으로 정렬. 숫자 정렬은 실제 크기 순으로 정렬
  • 예시: 7.0, 7.1, 10.0이 있다면, 숫자 정렬 결과는 10.0, 7.1, 7.0 순으로 정렬

3. 차이점 요약

  • 문자열 정렬: TO_CHAR로 변환된 값을 사용하여 정렬하며, 각 문자의 순서를 따름
  • 숫자 정렬: 숫자 값 자체를 사용하여 정렬하며, 실제 숫자 크기에 따라 순서 결정

4. 날짜 연산 (SQL Server vs Oracle)

연산SQL ServerOracle
현재 날짜GETDATE()SYSDATE
날짜 더하기DATEADD(DAY, 5, GETDATE())SYSDATE + 5
날짜 빼기DATEADD(DAY, -5, GETDATE())SYSDATE - 5
날짜 차이 계산DATEDIFF(DAY, '2023-01-01', GETDATE())SYSDATE - TO_DATE('2023-01-01', 'YYYY-MM-DD')
포맷팅FORMAT(GETDATE(), 'yyyy-MM-dd')TO_CHAR(SYSDATE, 'YYYY-MM-DD')
  • MS SQL server에서도 DATEDIFF 외에 빼기 연산 가능.

String, Date: 자동차 평균 대여 기간 구하기

정답쿼리

  • Oracle

SELECT CAR_ID, TO_CHAR(ROUND(AVG(RENT_DURATION), 1), 'FM999.0') AS AVERAGE_DURATION
FROM (
    SELECT HISTORY_ID, CAR_ID, (END_DATE - START_DATE + 1) AS RENT_DURATION
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
)
GROUP BY CAR_ID
HAVING ROUND(AVG(RENT_DURATION), 1) >= 7
ORDER BY ROUND(AVG(RENT_DURATION), 1) DESC, CAR_ID DESC;
  • MS SQL Server
SELECT CAR_ID, FORMAT(ROUND(AVG(RENT_DURATION), 1), '0.0') AS AVERAGE_DURATION
FROM (
    SELECT HISTORY_ID, CAR_ID, (END_DATE - START_DATE + 1) AS RENT_DURATION
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
)
GROUP BY CAR_ID
HAVING ROUND(AVG(RENT_DURATION), 1) >= 7
ORDER BY ROUND(AVG(RENT_DURATION), 1) DESC, CAR_ID DESC;
profile
헤매는 만큼 자기 땅이다.

0개의 댓글