Сравните DATETIME и DATE, игнорируя часть времени - PullRequest
135 голосов
/ 04 декабря 2009

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

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

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

Ответы [ 5 ]

232 голосов
/ 04 декабря 2009

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

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
58 голосов
/ 04 декабря 2009

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

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

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

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

  • Используйте дату как число с плавающей точкой.
  • Обрезать дробную часть
  • Привести значение обратно к дате
  • т.е. CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
4 голосов
/ 04 марта 2017

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

В общем, если вы фильтруете только по значениям Дата . 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
1 голос
/ 16 ноября 2017

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

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
0 голосов
/ 13 июня 2015

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

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

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

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

...