Как вернуть только дату из типа данных SQL Server DateTime - PullRequest
1607 голосов
/ 22 сентября 2008
SELECT GETDATE()

Возвращает: 2008-09-22 15:24:13.790

Я хочу эту часть даты без временной части: 2008-09-22 00:00:00.000

Как я могу получить это?

Ответы [ 43 ]

2309 голосов
/ 22 сентября 2008

На SQL Server 2008 и выше, вы должны CONVERT на сегодняшний день:

SELECT CONVERT(date, getdate())

В старых версиях вы можете делать следующее:

SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @your_date))

например

SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))

дает мне

2008-09-22 00:00:00.000

Плюсы:

  • Нет varchar <-> datetime требуется преобразование
  • Не нужно думать о locale
<Ч />

В соответствии с предложением Майкл

Используйте этот вариант: SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, getdate()))

select getdate()

SELECT DATEADD(hh, DATEDIFF(hh, 0, getdate()), 0)
SELECT DATEADD(hh, 0, DATEDIFF(hh, 0, getdate()))

SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, getdate()))

SELECT DATEADD(mm, DATEDIFF(mm, 0, getdate()), 0)
SELECT DATEADD(mm, 0, DATEDIFF(mm, 0, getdate()))

SELECT DATEADD(yy, DATEDIFF(yy, 0, getdate()), 0)
SELECT DATEADD(yy, 0, DATEDIFF(yy, 0, getdate()))

Выход:

2019-04-19 08:09:35.557

2019-04-19 08:00:00.000
4763-02-17 00:00:00.000

2019-04-19 00:00:00.000
2019-04-19 00:00:00.000

2019-04-01 00:00:00.000
1903-12-03 00:00:00.000

2019-01-01 00:00:00.000
1900-04-30 00:00:00.000
690 голосов
/ 24 сентября 2008

SQLServer 2008 теперь имеет тип данных date, который содержит только дату без компонента времени. Любой, кто использует SQLServer 2008 и более поздние версии, может выполнять следующие действия:

SELECT CONVERT(date, GETDATE())
157 голосов
/ 31 января 2011

Если используется SQL 2008 и выше:

select cast(getdate() as date)
70 голосов
/ 22 сентября 2008

DATEADD и DATEDIFF лучше, чем преобразование в varchar. Оба запроса имеют один и тот же план выполнения, но планы выполнения в основном касаются стратегий доступа data и не всегда показывают неявные затраты, связанные с затратами времени ЦП на выполнение всех частей. Если оба запроса выполняются для таблицы с миллионами строк, время ЦП с использованием DateDiff может быть близко к 1/3 времени преобразования ЦП!

Чтобы просмотреть планы выполнения запросов:

set showplan_text on
GO 

DATEADD и DATEDIFF будут выполнять CONVERT_IMPLICIT.

Хотя решение CONVERT проще и легче для некоторых, оно медленнее . Нет необходимости приводить обратно к datetime (это неявно делается сервером). Также нет необходимости в методе DateDiff для DateAdd, поскольку целочисленный результат также будет неявно преобразован обратно в datetime.


ВЫБРАТЬ КОНВЕРТ (varchar, MyDate, 101) ОТ DatesTable

  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(varchar(30),[TEST].[dbo].[DatesTable].[MyDate],101)))
       |--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))

ВЫБРАТЬ DATEADD (dd, 0, DATEDIFF (dd, 0, MyDate)) FROM DatesTable

  |--Compute Scalar(DEFINE:([Expr1004]=dateadd(day,(0),CONVERT_IMPLICIT(datetime,datediff(day,'1900-01-01 00:00:00.000',CONVERT_IMPLICIT(datetime,[TEST].[dbo].[DatesTable].[MyDate],0)),0))))
       |--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))

Использование FLOOR (), как предложено @digi, имеет производительность ближе к DateDiff, но не рекомендуется, так как приведение типа данных datetime к float и back не всегда приводит к исходному значению.

Помните, ребята: не верьте никому. Посмотрите статистику производительности и протестируйте ее сами!

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

У некоторых людей возникает путаница, когда оптимизация кэша влияет на запросы. Выполнение двух запросов в одном пакете или в разных пакетах не влияет на кэширование. Таким образом, вы можете либо завершить кеш вручную, либо просто выполнять запросы туда-сюда несколько раз. Любая оптимизация для запроса № 2 также повлияет на любые последующие запросы, поэтому, если хотите, исключите выполнение # 1.

Вот полный сценарий тестирования и результаты производительности , которые доказывают, что DateDiff существенно быстрее, чем преобразование в varchar.

45 голосов
/ 22 сентября 2008

Попробуйте это:

SELECT CONVERT(VARCHAR(10),GETDATE(),111)

Приведенный выше оператор преобразует ваш текущий формат в YYYY/MM/DD, пожалуйста, обратитесь к этой ссылке , чтобы выбрать предпочтительный формат.

37 голосов
/ 22 сентября 2008
SELECT CONVERT(datetime, CONVERT(varchar, GETDATE(), 101))
19 голосов
/ 22 сентября 2008

Вы можете использовать функцию CONVERT для возврата только даты. Смотрите ссылки ниже:

Манипуляции с датой и временем в SQL Server 2000

CAST и CONVERT

Синтаксис использования функции преобразования:

CONVERT ( data_type [ ( length ) ] , expression [ , style ] ) 
18 голосов
/ 19 декабря 2013

Для возврата в формате даты

CAST (Дата заказа как дата)

Приведенный выше код будет работать в SQL Server 2010

Он вернется, как 12/12/2013

Для SQL Server 2012 используйте следующий код

CONVERT(VARCHAR(10), OrderDate , 111)
13 голосов
/ 22 сентября 2011
SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),103) --21/09/2011

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),101) --09/21/2011

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),111) --2011/09/21

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),107) --Sep 21, 2011
12 голосов
/ 22 сентября 2008

Использование FLOOR () - просто вырезать часть времени.

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...