날짜 범위 간의 Postgresql 쿼리


126

날짜가 특정 월과 연도 인 결과를 반환하기 위해 내 postgresql db를 쿼리하려고합니다. 즉, 한 달 동안의 모든 값을 원합니다.

지금까지 내가 할 수 있었던 유일한 방법은 다음과 같습니다.

SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN '2014-02-01' AND '2014-02-28'

이 문제는 테이블을 쿼리하기 전에 첫 번째 날짜와 마지막 날짜를 계산해야한다는 것입니다. 이 작업을 수행하는 더 간단한 방법이 있습니까?

감사


간격은 항상 한 달입니까, 아니면 15 일에 시작하여 다음 달 7 일에 끝날 수 있습니까?
frlan 2014-04-28

답변:


202

날짜 (및 시간)를 사용하면 >= start AND < end.

예를 들면 :

SELECT
  user_id
FROM
  user_logs
WHERE
      login_date >= '2014-02-01'
  AND login_date <  '2014-03-01'

이 경우에도 필요한 달의 시작일을 계산해야하지만 여러 가지 방법으로 간단해야합니다.

종료 날짜도 간단합니다. 정확히 한 달만 추가하면됩니다. 28 일, 30 일, 31 일 등을 어지럽히 지 않습니다.


이 구조는 인덱스 사용을 유지할 수 있다는 장점도 있습니다.


많은 사람들이 다음과 같은 양식을 제안 할 수 있지만 색인을 사용 하지 않습니다 .

WHERE
      DATEPART('year',  login_date) = 2014
  AND DATEPART('month', login_date) = 2

여기에는 테이블의 모든 단일 행에 대한 조건 계산 (스캔)이 포함되며 인덱스를 사용하여 일치 할 행 범위를 찾지 않습니다 (범위 검색).


1
첫 번째 접근 방식은 몇 달 (일이 아닌) f.ex를 엉망으로 만들어야합니다. 2014-12-01& 2015-01-01. 두 번째도 인덱싱 할 수 있지만 사소한 것은 아닙니다 EXTRACT().
pozs

1
간격을 사용하여 애플리케이션에서 날짜 계산을 피할 수 있습니다. 예 : WHERE login_date> = '2014-02-01'AND login_date < '2014-02-01':: date + INTERVAL '1 month'코드를 단순화하면서 여전히 색인을 사용합니다.
baswell

53

PostreSQL 9.2부터 범위 유형 이 지원됩니다. 따라서 다음과 같이 작성할 수 있습니다.

SELECT user_id
FROM user_logs
WHERE '[2014-02-01, 2014-03-01]'::daterange @> login_date

이것은 문자열 비교보다 더 효율적이어야합니다


22

누군가 여기에 착륙하는 경우를 대비하여 ... 8.1부터 간단히 다음을 사용할 수 있습니다.

SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN SYMMETRIC '2014-02-01' AND '2014-02-28'

문서에서 :

BETWEEN SYMMETRIC은 AND의 왼쪽에있는 인수가 오른쪽에있는 인수보다 작거나 같아야한다는 요구 사항이 없다는 점을 제외하면 BETWEEN과 동일합니다. 그렇지 않은 경우이 두 인수가 자동으로 교체되므로 비어 있지 않은 범위가 항상 내포됩니다.


-1
SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN '2014-02-01' AND '2014-03-01'

Between 키워드는 데이트에 예외적으로 작동합니다. 날짜의 경우 시간이 00:00:00 (즉 자정)이라고 가정합니다.


-14

문서를 읽으십시오.

http://www.postgresql.org/docs/9.1/static/functions-datetime.html

다음과 같은 쿼리를 사용했습니다.

WHERE
(
    date_trunc('day',table1.date_eval) = '2015-02-09'
)

또는

WHERE(date_trunc('day',table1.date_eval) >='2015-02-09'AND date_trunc('day',table1.date_eval) <'2015-02-09')    

Juanitos Ingenier.


2
이것은 질문에 정확히 대답하지 않습니다. 질문은 월과 연도를 기준으로 날짜를 묻습니다.
Ram
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.