Запрос Postgresql между диапазонами дат


126

Я пытаюсь запросить мою базу данных postgresql, чтобы вернуть результаты, где дата находится в определенном месяце и году. Другими словами, мне нужны все значения за месяц-год.

Единственный способ, которым я смог это сделать, таков:

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

Проблема в том, что мне нужно вычислить первую и последнюю дату перед запросом таблицы. Есть способ сделать это попроще?

Спасибо


Всегда ли интервал составляет месяц или может быть, вы начинаете, может быть, 15-го числа и заканчиваете 7-го числа следующего месяца?
frlan

Ответы:


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
При первом подходе нужно возиться с месяцами (а не днями), например. 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


23

На всякий случай кто-нибудь приземлится здесь ... начиная с 8.1 вы можете просто использовать:

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

Из документов:

BETWEEN SYMMETRIC то же самое, что BETWEEN, за исключением того, что не требуется, чтобы аргумент слева от AND был меньше или равен аргументу справа. Если это не так, эти два аргумента автоматически меняются местами, так что всегда подразумевается непустой диапазон.


-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')    

Хуанитос Инжениер.


2
Это не совсем ответ на вопрос. Вопрос запрашивает даты в зависимости от месяца и года.
Ram
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.