PostgreSQL에서 날짜 시간 필드의 날짜를 비교하는 방법은 무엇입니까?


188

postgresql (Windows 버전 9.2.4)의 날짜를 비교할 때 이상한 시나리오에 직면했습니다. 테이블에 'timestamp without timezone'유형의 update_date 열이 있습니다. 고객은 날짜 (예 : 2013-05-03) 또는 시간이있는 날짜 (예 : 2013-05-03 12:20:00)만으로이 필드를 검색 할 수 있습니다. 이 열에는 현재 모든 행의 타임 스탬프 값이 있으며 날짜 부분 (2013-05-03)은 동일하지만 시간 부분의 차이가 있습니다.

이 열을 비교할 때 다른 결과가 나타납니다. 다음과 같이

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-03' -> No results

select * from table where update_date >= '2013-05-03' AND update_date < '2013-05-03' -> No results

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-04' -> results found

select * from table where update_date >= '2013-05-03' -> results found

내 질문은 첫 번째 쿼리를 사용하여 결과를 얻을 수있는 방법입니다. 왜 세 번째 쿼리가 작동하지만 첫 번째 쿼리는 작동하지 않습니까?

아무도 나를 도울 수 있습니까? 미리 감사드립니다.

답변:


278

@Nicolai는 전송 및 데이터에 대한 조건이 잘못된 이유에 대해 정확합니다. 입력 문자열에서 날짜 조작을 피하고 싶기 때문에 첫 번째 양식을 선호한다고 생각합니까? 당신은 두려워 할 필요가 없습니다 :

SELECT *
FROM table
WHERE update_date >= '2013-05-03'::date
AND update_date < ('2013-05-03'::date + '1 day'::interval);

이 구문 (인가 '2013-05-03'::date'1 day'::interval) PostgreSQL의 특정은?
Frozen Flame

5
@FrozenFlame 그렇습니다. 표준 구문은 CAST('2013-05-03' AS DATE) + CAST('1 day' AS INTERVAL)(IIRC)입니다. 존재와의 행동에 YMMV DATEINTERVAL.
단지 누군가

@FrozenFlame이 맞습니다. 문자열을 날짜 유형으로 캐스팅하지 않으면 대답이 작동하지 않습니다. 하나의 캐스트가 여전히 누락되었습니다. 있을 필요가 ::DATEwhere 절의 첫 부분에 추가
StillLearningToCode

WHERE update_date::date = '2013-05-03' 작동 하지 않고 약간 더 읽기 쉽습니다.
MikeF

@MikeF 영업 이익은 말했다 update_date이었다 timestamp without timezone. 해당 열의 색인을 가정했습니다. 술어는 해당 색인을 사용하지 않습니다.
누군가

46

update_date >= '2013-05-03'postgres 를 비교하면 값을 동일한 유형으로 캐스팅하여 값을 비교합니다. 따라서 '2013-05-03'은 '2013-05-03 00:00:00'으로 캐스팅되었습니다.

따라서 update_date = '2013-05-03 14:45:00'의 식은 다음과 같습니다.

'2013-05-03 14:45:00' >= '2013-05-03 00:00:00' AND '2013-05-03 14:45:00' <= '2013-05-03 00:00:00'

이것은 항상 false

이 문제를 해결하려면 update_date를 date다음으로 캐스팅하십시오 .

select * from table where update_date::date >= '2013-05-03' AND update_date::date <= '2013-05-03' -> Will return result

1
update_date쿼리 매개 변수의 단일 값을 캐스팅하는 것과 테이블의 모든 캐스팅은 매우 비효율적이며 서버가 해당 열의 인덱스를 활용할 수 없도록합니다. 나는 이것을 -1로 유혹하고있다.
단지 누군가

3
예, 각 값의 캐스팅이 비효율적이며이 솔루션에 대해 -1을 줄 수 있음에 동의합니다. 그러나 문제의 이유를 설명하고 문제를 보여주는 예를 제시했습니다. 이제 user2866264는 자신의 쿼리가 예상 행을 반환하지 않는 이유를 알고 있으며 고유 한 경우에 정확히 어떤 솔루션이 더 적합한지를 결정할 것입니다.
Nicolai

@Nicolai : 답변 해 주셔서 감사합니다. 그것은 당신의 대답에 따라 작동합니다. 설명 주셔서 감사합니다.
user2866264

1
@Nicolai – Postgres가 날짜 리터럴을 자정까지 확장 한 것에 대해 말씀 드린 바, 목표가 단일 날짜 (5 월 3 일)로 표시된 레코드를 찾는 경우이 코드가 정확하고 효율적일 SELECT * FROM my_table WHERE update_date >= '2013-05-03' AND update_date < '2013-05-04'; 것입니다 (5 월 4 일 사용에 유의). 3 등보다는 덜 평등하지 않은
징조가


2

날짜 변환을 사용하여 날짜와 비교하십시오.

select * from table 
where TO_DATE(to_char(timespanColumn,'YYYY-MM-DD'),'YYYY-MM-DD') = to_timestamp('2018-03-26', 'YYYY-MM-DD')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.