Сравните DATETIME и DATE, игнорируя часть времени

151

У меня есть две таблицы, где столбец [date]типа DATETIME2(0).

Я должен сравнить две записи только по их частям Date (день + месяц + год), отбрасывая части Time (часы + минуты + секунды).

Как я могу это сделать?

abatishchev
источник

Ответы:

252

Используйте CASTдля нового DATEтипа данных в SQL Server 2008, чтобы сравнить только часть даты:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
marc_s
источник
61

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

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

  • Индексированное поле даты (назовите его DF1) должно быть не затронуто любой функцией.
  • Таким образом, вы должны сравнить DF1 с полным диапазоном значений даты и времени для дня DF2.
  • Это от даты-части DF2 до даты-части дня после DF2.
  • Т.е. (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • ПРИМЕЧАНИЕ . Очень важно, чтобы сравнение составляло > = (допустимое равенство) до даты DF2 и (строго) < день после DF2. Также оператор BETWEEN не работает, потому что он допускает равенство с обеих сторон.

PS: Другой способ извлечения только даты (в более старых версиях SQL Server) заключается в использовании хитрости представления даты внутри.

  • Введи дату как поплавок.
  • Усекать дробную часть
  • Приведите значение обратно к дате
  • Т.е. CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
разочарованный
источник
5

Хотя я проголосовал за ответ, помеченный как правильный. Я хотел бы коснуться нескольких вещей для любого, кто наткнулся на это.

В общем, если вы фильтруете только по значениям Date . Microsoft рекомендует использовать не зависящий от языка формат ymdили y-m-d.

Обратите внимание, что форма «2007-02-12» считается независимой от языка только для типов данных DATE, DATETIME2 и DATETIMEOFFSET.

Сделать сравнение дат с использованием вышеупомянутого подхода просто. Рассмотрим следующий надуманный пример.

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    CONVERT(char(8), OrderDate, 112) = @filterDate

В идеальном мире следует избегать любых манипуляций с отфильтрованным столбцом, поскольку это может помешать SQL Server эффективно использовать индексы. Тем не менее, если данные, которые вы сохраняете, касаются только даты, а не времени, рассмотрите возможность хранения как DATETIMEс полуночи, так и со временем. Так как:

Когда SQL Server преобразует литерал в тип отфильтрованного столбца, он предполагает полночь, когда часть времени не указана. Если вы хотите, чтобы такой фильтр возвращал все строки с указанной даты, вам нужно убедиться, что вы храните все значения с полночью как временем.

Таким образом, предполагая, что вас интересует только дата, и сохраните свои данные как таковые. Вышеуказанный запрос может быть упрощен до:

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate
pimbrouwers
источник
3

Вы можете попробовать это

CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')

Я проверяю это для MS SQL 2014 с помощью следующего кода

select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
            else '' end
reza.cse08
источник
-3

Для сравнения две даты, такие как ММ / ДД / ГГГГ в ММ / ДД / ГГГГ . Помните, что первым делом тип столбца Field должен быть dateTime. Пример: columnName: payment_date dataType: DateTime .

после этого вы можете легко сравнить это. Запрос это:

select  *  from demo_date where date >= '3/1/2015' and date <=  '3/31/2015'.

Это очень просто ...... Это проверило это .....

Панкай
источник
Это не совсем отвечает на вопрос. Запрашивает месяц, а не день.
Кертис Яллоп
Для вашего запроса в марте: если дата «31.03.2015» время 13:00, она не будет найдена. Вы должны использовать <'1/4/2015'.
Кертис Яллоп
Также рассмотрите возможность использования международного формата даты «2015-03-01». В Канаде (и многих других местах) официальным форматом является DD / MM / YYYY, что делает оба формата неоднозначными и проблемными.
Кертис Яллоп
Этот ответ не относится к 2 таблицам, как указано в вопросе.
Кертис Яллоп
Да, я согласен, но я просто проверяю решение, а не международное решение .. Вы должны изменить какой-то порядок ...
pankaj