PostgreSQL — фильтрация диапазона дат

Я разработчик SQL и большую часть времени провожу в MSSQL. Я ищу лучший способ отфильтровать поле «Временная метка без часового пояса» в БД PostgreSQL.

Я использую:

Where 
DateField >= '2010-01-01' and 
DateField < '2012-01-01'

Но учитывая, что я не эксперт в синтаксисе, я должен думать, что есть лучший способ.

Какие-либо предложения? Спасибо.


person Rob S    schedule 04.04.2013    source источник
comment
Что в этом плохого? Вы можете использовать between 2010-01-01 и 2012-01-01`, но на самом деле это почти то же самое. Есть ли лучший способ сделать это с помощью MSSQL (я никогда его не использовал)?   -  person Andre    schedule 04.04.2013
comment
@Andre Лучше явно указать формат даты.   -  person Ihor Romanchenko    schedule 04.04.2013
comment
Все нормально, просто долго идет. Я убедился, что в поле есть индекс, но это занимает гораздо больше времени, чем я привык.   -  person Rob S    schedule 04.04.2013
comment
У меня никогда не было проблем со сравнением таких дат, и я обычно не индексирую свои даты. @RobS вы работаете со смехотворно большими объемами данных? Вы присоединяетесь к группе столов вместе?   -  person Andre    schedule 04.04.2013
comment
Одна таблица, доставшаяся мне по наследству. Я ожидаю, что вернется около 3-4 миллионов строк.   -  person Rob S    schedule 04.04.2013


Ответы (3)


Ваше решение в порядке. Однако, если даты являются литеральными, я бы предпочел:

WHERE datefield >= '2010-01-01 00:00:00' 
 AND  datefield <  '2012-01-01 00:00:00'

Это работает точно так же, но более удобно в сопровождении, потому что ясно указывает на то, что каждая буквальная «дата» является отметкой времени, а не датой. Например, предположим, что кто-то меняет ваш запрос на следующий

    AND  datefield <=  '2012-01-01'

... ожидая (и не в состоянии) включить в запрос полный день "2012-01-01". В более позднем синтаксисе намерение становится более ясным, и эта путаница предотвращается.

Чтобы сделать это еще более понятным (возможно, слишком многословным), вы можете выполнить явное приведение типов:

WHERE datefield >= '2010-01-01 00:00:00'::timestamp 
 AND  datefield <  '2012-01-01 00:00:00'::timestamp

Я бы не стал использовать здесь ни to_date() по тем же причинам (возможна путаница с типами данных), ни to_timestamp() (он возвращает timestamptz).

Кстати, я изменил регистр в соответствии с рекомендуемой практикой (ключевые слова в верхнем регистре, идентификаторы в нижнем регистре).

person leonbloy    schedule 04.04.2013
comment
Вы можете использовать BETWEEN, если вы будете использовать --ваш пример-- '2010-01-01 00:00:00'::timestamp в качестве начальной даты и времени и '2010-01-01 24:00:00':: отметка времени в конце. - person thisfeller; 04.04.2013

Для интервалов дат вы можете использовать что-то вроде:

WHERE DateField BETWEEN to_date('2010-01-01','YYYY-MM-DD') 
                    AND to_date('2010-01-02','YYYY-MM-DD')

Он короче (вам не нужно повторять DateField) и имеет явный формат даты.

За 1 час/день/месяц/год можно использовать:

WHERE date_trunc('day',DateField) = to_date('2010-01-01','YYYY-MM-DD')
person Ihor Romanchenko    schedule 04.04.2013
comment
between не то же самое, что >= and <, так как включает оба конца. - person Clodoaldo Neto; 04.04.2013
comment
@ClodoaldoNeto Для временных меток (как уже упоминалось в вопросе) разница составляет одну миллисекунду. - person Ihor Romanchenko; 04.04.2013

Вы можете сделать запрос простым, используя BETWEEN, если имя вашего столбца имеет тип TIMESTAMP, а имя вашего столбца не является "отметкой времени"...

SELECT * FROM table WHERE column BETWEEN '2018-12-30 02:19:34' AND '2018-12-30 02:25:34'

Это работает для дат «2018-12-30» и даты-времени «2018-12-30 02:19:34».

person Phil Andrews    schedule 31.12.2018