[sql] Timestamp 및 Extract
시간 값 저장하기
✅ TIME – 시간 값 저장 (시, 분, 초만 포함)
SELECT TIME '14:30:00';
오후 2시 30분을 나타내는 TIME 값
✅ DATE – 날짜 값 저장 (연, 월, 일만 포함)
SELECT DATE '2025-02-16';
2025년 2월 16일을 나타내는 DATE 값
✅ TIMESTAMP – 날짜 및 시간 저장 (초까지 포함)
SELECT TIMESTAMP '2025-02-16 14:30:00';
2025년 2월 16일 오후 2시 30분을 나타내는 TIMESTAMP 값
✅ TIMESTAMPTZ – 타임존을 포함한 날짜 및 시간 저장
SELECT TIMESTAMPTZ '2025-02-16 14:30:00+09';
한국 시간(KST) 기준으로 2025년 2월 16일 오후 2시 30분 저장
타임존을 정확히 저장하고 변환할 때 필요
시간 값 조회하기
✅ TIMEZONE 설정 및 조회
SHOW TIMEZONE;
현재 데이터베이스의 타임존 확인
✅ NOW – 현재 날짜 및 시간 조회
SELECT NOW();
현재 날짜와 시간을 반환 (타임존 포함)
✅ TIMEOFDAY – 현재 시간 및 시스템 정보 조회
SELECT TIMEOFDAY();
현재 시간과 타임존 정보를 문자열로 반환
✅ CURRENT_TIME – 현재 시간 조회
SELECT CURRENT_TIME;
- 현재 시간(HH:MM:SS) 반환
✅ CURRENT_DATE – 현재 날짜 조회
SELECT CURRENT_DATE;
- 오늘 날짜 반환
날짜에서 특정 값 추출
✅ EXTRACT – 날짜에서 특정 값 추출
SELECT EXTRACT(YEAR FROM NOW());
- 현재 연도 값 추출
SELECT EXTRACT(YEAR FROM payment_date) AS myyear
FROM payment
-- 2007
- Alias와 사용하면 좋음
✅ AGE – 특정 날짜 기준으로 경과 시간 계산
SELECT AGE('2000-01-01');
- 2000년 1월 1일부터 현재까지의 경과 시간 계산
SELECT AGE(payment_date)
FROM payment
✅ TO_CHAR – 날짜 및 시간 포맷 변환
PostgreSQL 데이터 타입 포맷 변환: https://www.postgresql.org/docs/current/functions-formatting.html
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS');
현재 날짜와 시간을 'YYYY-MM-DD HH:MM:SS' 형식의 문자열로 변환
하나의 데이터 형식을 문자 형식으로 바꿔줌
SELECT TO_CHAR(payment_date, 'MONTH-YYYY')
FROM payment
✨ In English:
TIME
stores only the time (HH:MM:SS).DATE
stores only the date (YYYY-MM-DD).TIMESTAMP
stores both date and time without a timezone.TIMESTAMPTZ
stores both date and time with a timezone.SHOW TIMEZONE
displays the current database timezone.NOW()
returns the current timestamp with timezone.TIMEOFDAY()
returns the current time and system info as a string.CURRENT_TIME
returns the current time.CURRENT_DATE
returns the current date.EXTRACT()
retrieves a specific part of a date value.AGE()
calculates the difference between a given date and the current date.TO_CHAR()
converts date values into formatted text.
📝 오늘 배운 점:
날짜 및 시간 데이터를 저장할 때 타임존이 필요한지 여부를 고려해야 한다.
TIMESTAMPTZ
를 사용하면 타임존을 자동 변환할 수 있어 글로벌 서비스에서 유용하다.NOW()
와CURRENT_DATE
는 현재 시간을 자동으로 가져올 때 자주 사용된다.EXTRACT()
를 사용하면 연도, 월, 일 같은 특정 값을 쉽게 추출할 수 있다.AGE()
를 활용하면 나이 계산이나 특정 날짜와의 차이를 구할 수 있다.TO_CHAR()
를 사용하면 날짜를 원하는 형식으로 변환할 수 있어 출력 시 유용하다.날짜 데이터를 다룰 때는 미래에 필요한 데이터를 잃지 않도록 신중하게 설계하는 것이 중요하다.
연습 문제
연습 문제 1
During which months did payments occur?
Format your answer to return back the full month name.
SELECT DISTINCT(TO_CHAR(payment_date,'MONTH')) FROM payment
연습 문제 2
- How many payments occurred on a Monday?
첫 번째 시도
SELECT COUNT(*)
FROM payment
WHERE TO_CHAR(payment_date,'DAY') = 'MONDAY'
결과가 0이 나옴 (답은 2948)
문제 원인
TO_CHAR(payment_date, 'DAY')
의 결과에는 공백이 포함될 수 있음.
TO_CHAR(payment_date, 'DAY')
는 요일을 고정된 길이로 출력하므로,MONDAY
뒤에 공백이 포함될 가능성이 있음.예를 들어, 결과가
'MONDAY '
(공백 포함)이라면'MONDAY'
와 비교할 때 일치하지 않아서 조건이 false가 됨.
- 대소문자 문제
TO_CHAR()
의 기본 출력은 대문자지만, 환경에 따라 다를 수 있음.만약
'monday'
처럼 소문자로 비교하면 일치하지 않을 수도 있음.
두 번째 시도
SELECT COUNT(*)
FROM payment
WHERE TRIM(TO_CHAR(payment_date, 'DAY')) = 'MONDAY';
- TRIM(공백 제거)을 사용해서 해결
정답
EXTRACT 함수 사용.
PostgreSQL은 일요일을 한 주의 시작으로 생각해서 일요일의 인덱스가 0임.
SELECT COUNT(*)
FROM payment
WHERE EXTRACT(dow FROM payment_date) = 1 -- 월요일은 1
EXTRACT(dow FROM payment_date)
는 날짜에서 요일을 숫자로 추출하는 함수.dow
는 0(일)~6(토) 사이의 숫자로 요일을 표현.문자열 비교(
TO_CHAR
) 대신 숫자로 비교할 수 있어 더 깔끔하고 성능도 좋을 수 있음.