Сравните строку даты с датой и временем в SQL Server?

В 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 секунду до полуночи).

14.08.2008 09:14:07
18 ОТВЕТОВ
РЕШЕНИЕ

Техника 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, если он существует.

37
13.08.2012 22:13:50
Я считаю, что CAST («14 августа 2008» как DateTime) немного лучше. Я думаю, что это немного более читабельно, и я считаю, что CAST более переносим, ​​чем CONVERT (), поскольку CAST () совместим с ANSI SQL-92 и -99
Larry OBrien 24.09.2008 21:44:23
Вы можете использовать ключевое слово BETWEEN в качестве сокращения этого ответа.
Möoz 16.08.2013 06:42:46
@BorhanMooz, на самом деле, МЕЖДУ не фиксирует промежуточность> = / <, приведенную в коде. МЕЖДУ полностью включено ( technet.microsoft.com/en-us/library/ms187922.aspx , «Значение результата»).
Bondolin 16.08.2013 17:31:03
SELECT  *
FROM    table1
WHERE   CONVERT(varchar(10),columnDatetime,121) = 
        CONVERT(varchar(10),CONVERT('14 AUG 2008' ,smalldatetime),121)

Это преобразует время данных и строку в варианты в формате «ГГГГ-ММ-ДД».

Это очень некрасиво, но должно работать

1
14.08.2008 09:28:02

Техника 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 () будет короче.

4
14.08.2008 09:27:44

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

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)
8
14.08.2008 09:19:55

Эта функция 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
3
14.08.2008 09:27:56
Разве несколько функций, примененных к полю (если они проиндексированы), не преобразуют это в полное сканирование таблицы?
Manuel Ferreria 18.05.2009 13:19:23

Я знаю, что это не совсем то, что вы хотите сделать, но это может быть началом:

SELECT *
FROM (SELECT *, DATEPART(yy, column_dateTime) as Year, 
      DATEPART(mm, column_dateTime) as Month, 
      DATEPART(dd, column_dateTime) as Day 
      FROM table1)
WHERE Year = '2008'
AND Month = '8'
AND Day = '14'
1
14.08.2008 09:22:54

Что-то вроде этого?

SELECT  *
FROM    table1
WHERE   convert(varchar, column_datetime, 111) = '2008/08/14'
4
14.08.2008 09:23:23

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

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

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

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

И для моего :

18
15.08.2008 13:04:58

Как получить часть 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
18.05.2009 15:52:40
SELECT CONVERT(VARCHAR(2),DATEPART("dd",doj)) + 
    '/' + CONVERT(VARCHAR(2),DATEPART("mm",doj)) + 
    '/' + CONVERT(VARCHAR(4),DATEPART("yy",doj)) FROM emp
0
7.03.2016 18:15:20
DECLARE @Dat

SELECT * 
FROM Jai
WHERE                                                                                                          
CONVERT(VARCHAR(2),DATEPART("dd",Date)) +'/'+                                                              
             CONVERT(VARCHAR(2),DATEPART("mm",Date)) +'/'+              
                     CONVERT(VARCHAR(4), DATEPART("yy",Date)) = @Dat
1
7.03.2016 18:03:03

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

Тем не менее, если вы действительно выполняете поиск только по определенным 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
16.02.2010 07:51:10
и затем я предлагаю использовать один из форматов ISO для дат, которые распознает большинство баз данных и не зависит от языка / локали, например,YYYY-MM-DD
van 16.02.2010 09:02:20

В sqlserver

DECLARE @p_date DATE

SELECT * 
FROM table1
WHERE column_dateTime=@p_date

В C # Передайте короткую строку значения даты, используя функцию ToShortDateString (). sample: DateVariable.ToShortDateString ();

-1
7.03.2016 17:29:34

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

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


SELECT * FROM table
WHERE CONVERT(VARCHAR(15),dtInvoice, 112)>= CONVERT(VARCHAR(15),@strDate , 112)
1
7.12.2010 06:15:08
SELECT * FROM tablename
WHERE CAST(FLOOR(CAST(column_datetime AS FLOAT))AS DATETIME) = '30 jan 2012'
0
7.03.2016 18:05:29

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

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
4
24.02.2012 22:53:56

Лучший способ - просто извлечь часть даты с помощью функции SQL DATE ():

SELECT * 
FROM table1
WHERE DATE(column_datetime) = @p_date;
0
23.05.2015 15:42:08

Существует множество форматов даты в SQL, которые указываются. См. Https://msdn.microsoft.com/en-in/library/ms187928.aspx

Преобразование и сравнение столбца varchar с выбранными датами.

Синтаксис:

SELECT * FROM tablename where CONVERT(datetime,columnname,103) 
    between '2016-03-01' and '2016-03-03'
In CONVERT(DATETIME,COLUMNNAME,103) "103" SPECIFIES THE DATE FORMAT as dd/mm/yyyy
0
8.03.2016 20:37:04