Сравните строку даты с датой и временем в SQL Server? - PullRequest
39 голосов
/ 14 августа 2008

В SQL Server у меня есть столбец DATETIME, который включает элемент времени.

Пример:

'14 AUG 2008 14:23:019'

Каков лучший метод для выбора записей только для определенного дня, игнорируя часть времени?

Пример: (небезопасно, так как не соответствует временной части и не возвращает строк)

DECLARE  @p_date DATETIME
SET      @p_date = CONVERT( DATETIME, '14 AUG 2008', 106 )

SELECT *
FROM   table1
WHERE  column_datetime = @p_date

Примечание. Учитывая, что этот сайт также посвящен написанию заметок и приемов, которые вы выбираете, а затем забываете, я собираюсь опубликовать свой собственный ответ на этот вопрос, поскольку материал DATETIME в MSSQL, вероятно, является темой, которую я больше всего ищу в SQLBOL.


Обновление Уточненный пример, чтобы быть более конкретным.


Редактировать Извините, но мне пришлось преуменьшить НЕПРАВИЛЬНЫЕ ответы (ответы, которые возвращают неправильные результаты).

@ Jorrit: WHERE (date>'20080813' AND date<'20080815') вернется 13-го и 14-го.

@ wearejimbo: Близко, но без сигары! Знак вручен вам. Вы пропустили записи, написанные в 14/08/2008 с 23: 59: 001 до 23: 59: 999 (т. Е. Менее чем за 1 секунду до полуночи.)

Ответы [ 18 ]

36 голосов
/ 14 августа 2008

Техника 1:

 DECLARE @p_date DATETIME
 SET     @p_date = CONVERT( DATETIME, '14 AUG 2008', 106 )

 SELECT  *
 FROM    table1
 WHERE   column_datetime >= @p_date
 AND     column_datetime < DATEADD(d, 1, @p_date)

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

16 голосов
/ 14 августа 2008

В SQL Server 2008 вы можете использовать новый тип данных DATE

DECLARE @pDate DATE='2008-08-14'  

SELECT colA, colB
FROM table1
WHERE convert(date, colDateTime) = @pDate  

@ Guy. Я думаю, вы найдете, что это решение отлично масштабируется. Взгляните на план выполнения запроса вашего исходного запроса.

А для мой :

8 голосов
/ 14 августа 2008

Просто сравните значения года, месяца и дня.

Declare @DateToSearch DateTime
Set @DateToSearch = '14 AUG 2008'

SELECT * 
FROM table1
WHERE Year(column_datetime) = Year(@DateToSearch)
      AND Month(column_datetime) = Month(@DateToSearch)
      AND Day(column_datetime) = Day(@DateToSearch)
4 голосов
/ 16 февраля 2010

Хороший вопрос об индексе в ответе, который вы приняли.

Тем не менее, если вы действительно выполняете поиск только по определенным DATE или DATE ranges часто , то лучшее решение, которое я нашел, - это добавить еще один постоянный вычисляемый столбец в вашу таблицу, который будет содержать только DATE и добавьте индекс в этот столбец:

ALTER TABLE "table1" 
    ADD "column_date" AS CONVERT(DATE, "column_datetime") PERSISTED

Добавить индекс к этому столбцу:

CREATE NONCLUSTERED INDEX "table1_column_date_nu_nci"
ON  "table1" ( "column_date" ASC )
GO

Тогда ваш поиск будет еще быстрее:

DECLARE  @p_date DATE
SET      @p_date = CONVERT( DATE, '14 AUG 2008', 106 )

SELECT   *
FROM     table1
WHERE    column_date = @p_date
4 голосов
/ 14 августа 2008

Как то так?

SELECT  *
FROM    table1
WHERE   convert(varchar, column_datetime, 111) = '2008/08/14'
4 голосов
/ 14 августа 2008

Техника 2:

DECLARE @p_date DATETIME
SET     @p_date = CONVERT( DATETIME, '14 AUG 2008', 106 )

SELECT  *
FROM    table1
WHERE   DATEDIFF( d, column_datetime, @p_date ) = 0

Если поле column_datetime не проиндексировано и вряд ли будет (или индекс вряд ли будет использоваться), тогда использование DATEDIFF () короче.

3 голосов
/ 25 февраля 2012

Обычно я конвертирую дату и время в дату и сравниваю их, например:

SELECT 'Same Date' WHERE CAST(getDate() as date) = cast('2/24/2012 2:23 PM' as date)

или

SELECT 'Same Date' WHERE DATEDIFF(dd, cast(getDate() as date), cast('2/24/2012 2:23 PM' as date)) = 0
3 голосов
/ 18 августа 2008

Как получить часть DATE поля DATETIME в MS SQL Server:

Один из самых быстрых и удобных способов сделать это - использовать

DATEADD(dd, DATEDIFF( dd, 0, @DAY ), 0)

Это позволяет избежать перегрузки ЦП "преобразование даты в строку без времени и последующее преобразование ее обратно".

Это также не раскрывает внутреннюю реализацию того, что «часть времени выражается в виде дроби» даты.

Получить дату первого дня месяца

DATEADD(dd, DATEDIFF( dd, -1, GetDate() - DAY(GetDate()) ), 0)

Получить дату 1 год назад

DATEADD(m,-12,DATEADD(dd, DATEDIFF( dd, -1, GetDate() - DAY(GetDate()) ), 0))
3 голосов
/ 14 августа 2008

Эта функция Cast (Floor (Cast (GetDate () As Float)) As DateTime) возвращает тип данных datetime с удаленной частью времени и может использоваться следующим образом.

Select
*
Table1
Where
Cast(Floor(Cast(Column_DateTime As Float)) As DateTime) = '14-AUG-2008'

или

DECLARE  @p_date DATETIME
SET      @p_date = Cast('14 AUG 2008' as DateTime)

SELECT   *
FROM     table1
WHERE    Cast(Floor(Cast(column_datetime As Float)) As DateTime) = @p_date
1 голос
/ 07 декабря 2010

Дату можно сравнить в sqlserver, используя сравнение строк: например,

DECLARE @strDate VARCHAR(15)
SET @strDate ='07-12-2010'


SELECT * FROM table
WHERE CONVERT(VARCHAR(15),dtInvoice, 112)>= CONVERT(VARCHAR(15),@strDate , 112)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...