Самый эффективный способ в SQL Server получить дату от даты+времени?


в MS SQL 2000 и 2005, учитывая datetime, такие как' 2008-09-25 12:34:56 'каков наиболее эффективный способ получить datetime, содержащий только'2008-09-25'?

Дублированный здесь.

11 72

11 ответов:

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

я протестировал чистый выбор (который вернет дату и время, а не то, что мы хотим), царствующее решение здесь (floor-float), общий "наивный", упомянутый здесь (stringconvert) и тот, который я использовал (поскольку я думал, что это самый быстрый).

Я проверил запросы на тестовом сервере MS SQL Server 2005, работающем на сервере Win 2003 SP2 с помощью Процессор Xeon 3GHz работает на максимальной памяти (32 бит, так что это около 3,5 Гб). Это ночь, где я нахожусь, поэтому машина работает на холостом ходу почти без нагрузки. У меня есть все это для себя.

вот журнал из моего тестового запуска, выбираемый из большой таблицы, содержащей временные метки, изменяющиеся до миллисекундного уровня. Этот конкретный набор данных включает даты в диапазоне более 2,5 лет. Сама таблица имеет более 130 миллионов строк, поэтому я ограничиваюсь верхним миллионом.

SELECT TOP 1000000 CRETS FROM tblMeasureLogv2 
SELECT TOP 1000000 CAST(FLOOR(CAST(CRETS AS FLOAT)) AS DATETIME) FROM tblMeasureLogv2
SELECT TOP 1000000 CONVERT(DATETIME, CONVERT(VARCHAR(10), CRETS, 120) , 120) FROM tblMeasureLogv2 
SELECT TOP 1000000 DATEADD(DAY, DATEDIFF(DAY, 0, CRETS), 0) FROM tblMeasureLogv2

время синтаксического анализа и компиляции SQL Server: время процессора = 0 мс, затраченное время = 1 мс.

(1000000 строк (ов) затронуты) таблица 'tblMeasureLogv2'. Число просмотров 1, логических чтений 4752, физических чтений 0, упреждающих чтений 0, LOB логических чтений 0, LOB физических чтений 0, LOB упреждающих чтений 0.

время выполнения SQL Server: процессорное время = 422 МС, затраченное время = 33803 МС.

(1000000 строк (ов) затронуты) таблица 'tblMeasureLogv2'. Число просмотров 1, логических чтений 4752, физических чтений 0, упреждающих чтений 0, LOB логических чтений 0, LOB физических чтений 0, LOB упреждающих чтений 0.

время выполнения SQL Server: процессорное время = 625 МС, затраченное время = 33545 МС.

(1000000 строк (ов) затронуты) таблица 'tblMeasureLogv2'. Число просмотров 1, логических чтений 4752, физических чтений 0, упреждающих чтений 0, LOB логических чтений 0, LOB физических чтений 0, LOB упреждающих чтений 0.

время выполнения SQL Server: процессорное время = 1953 МС, затраченное время = 33843 МС.

(1000000 строк (ов) затронуты) таблица 'tblMeasureLogv2'. Число просмотров 1, логических чтений 4752, физических чтений 0, упреждающих чтений 0, LOB логических чтений 0, LOB физических чтений 0, LOB упреждающих чтений 0.

SQL сервер времени выполнения: время ЦП = 531 МС, затраченное время = 33440 МС. Сервер SQL разбора и компиляции: время ЦП = 0 мс, истекшее время = 1 мс.

время выполнения SQL Server: процессорное время = 0 мс, затраченное время = 1 ms.

что мы здесь видим?

давайте сосредоточимся на процессорном времени (мы смотрим на преобразование), и мы видим, что у нас есть следующие цифры:

Pure-Select:  422
Floor-cast:   625
String-conv: 1953
DateAdd:      531  

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

прежде чем вы пойдете туда, я провел этот тест несколько раз, с измененным порядком запросов, одинаковыми результатами.

это что-то странно на моем сервере, что ли?

Select DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)

функция datediff(День, 0, getdate()) для такой же, как и функция datediff(день, '1900-01-01', getdate ()) для

поскольку DateDiff возвращает целое число, вы получите количество дней, прошедших с 1 января 1900 года. Затем вы добавляете это целое число дней к 1 января 1900 года. Чистый эффект заключается в удалении компонента времени.

Я должен также упомянуть, что этот метод работает для любой даты/времени (например, год, квартал, месяц, день, час, минуту и второй.)

Select  DateAdd(Year, DateDiff(Year, 0, GetDate()), 0)
Select  DateAdd(Quarter, DateDiff(Quarter, 0, GetDate()), 0)
Select  DateAdd(Month, DateDiff(Month, 0, GetDate()), 0)
Select  DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)
Select  DateAdd(Hour, DateDiff(Hour, 0, GetDate()), 0)
Select  DateAdd(Second, DateDiff(Second, '20000101', GetDate()), '20000101')

последний, в течение нескольких секунд, требует специальной обработки. Если вы используете 1 января 1900 года вы получите сообщение об ошибке.

разница двух столбцов datetime вызвала переполнение во время выполнения.

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

select cast(floor(cast(@datetime as float)) as datetime)

работает, потому что приведение datetime к float дает количество дней (включая доли дня) с 1 января 1900 года. Настил он удаляет дробные дни и оставляет количество целых дней, которые затем могут быть отброшены обратно в datetime.

в SQL server 2012 используйте

select cast(getdate() as date)
select cast(getdate()as varchar(11))as datetime

чтобы получить гггг-ММ-ДД, используйте:

select convert(varchar(10), getdate(), 120)

Edit: Ой, он хочет дату и время вместо строки. Эквивалент TRUNC () в Oracle. Вы можете взять то, что я опубликовал и вернуть в DateTime:

select convert(datetime, convert(varchar(10), getdate(), 120) , 120)

CONVERT, FLOOR, и DATEDIFF будет выполнять то же самое.

как вернуть часть даты только из типа данных SQL Server datetime

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

http://www.blackwasp.co.uk/SQLDateFromDateTime.aspx

CAST(FLOOR(CAST(yourdate AS DECIMAL(12, 5))) AS DATETIME) выполняет лучшее на сегодняшний день. вы можете увидеть доказательство и тесты, когда получение даты без времени в sql server

А Как Же SELECT CAST(CASt(GETDATE() AS int) AS DATETIME)??

CONVERT(VARCHAR(10), GETDATE(), 120) AS [YYYY-MM-DD]