Сравнить строку даты с datetime в 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 секунду до полуночи).
Ответов (18)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, если он существует.
Техника 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 () будет короче.
В sqlserver
DECLARE @p_date DATE
SELECT *
FROM table1
WHERE [email protected]_date
В C# передайте короткую строку значения даты с помощью функции ToShortDateString (). пример: DateVariable.ToShortDateString ();
В 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
В SQL Server 2008 вы можете использовать новый тип данных DATE
DECLARE @pDate DATE='2008-08-14'
SELECT colA, colB
FROM table1
WHERE convert(date, colDateTime) = @pDate
@Парень. Я думаю, вы обнаружите, что это решение отлично масштабируется. Взгляните на план выполнения исходного запроса.
А для меня :
Эта функция 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
Как получить часть DATE поля DATETIME в MS SQL Server:
Один из самых быстрых и удобных способов сделать это - использовать
DATEADD(dd, DATEDIFF( dd, 0, @DAY ), 0)
Это позволяет избежать перебора ЦП логики «преобразовать дату в строку без времени и затем снова преобразовать ее».
Он также не раскрывает внутреннюю реализацию, согласно которой «часть времени выражается в виде дроби» даты.
Получить дату первого числа месяца
DATEADD(dd, DATEDIFF( dd, -1, GetDate() - DAY(GetDate()) ), 0)
Получить дату rfom 1 год назад
DATEADD(m,-12,DATEADD(dd, DATEDIFF( dd, -1, GetDate() - DAY(GetDate()) ), 0))
Хорошее замечание об указателе в принятом вами ответе.
Тем не менее, если вы действительно выполняете поиск только по конкретному 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