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

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

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

Ответ 1

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

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

Я протестировал запросы на тестовом сервере MS SQL Server 2005, запущенном на сервере Windows 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: время CPU = 0 мс, прошедшее время = 1 мс.

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

Время выполнения SQL Server: время процессора = 422 мс, прошедшее время = 33803 мс.

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

Время выполнения SQL Server: время процессора = 625 мс, прошедшее время = 33545 мс.

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

Время выполнения SQL Server: время процессора = 1953 мс, прошедшее время = 33843 мс.

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

Время выполнения SQL Server: время процессора = 531 мс, прошедшее время = 33440 мс. Время и время компиляции SQL Server: время CPU = 0 мс, прошедшее время = 1 мс.

Время выполнения SQL Server: время процессора = 0 мс, прошедшее время = 1 мс.

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

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

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

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

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

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

Ответ 2

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

DateDiff (День, 0, GetDate()) совпадает с DateDiff (День, '1900-01-01', GetDate())

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

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

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 г.).

Ответ 3

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

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

Ответ 4

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

select cast(getdate() as date)

Ответ 5

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

Ответ 6

Чтобы получить YYYY-MM-DD, используйте:

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

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

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

Ответ 10

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

Ответ 11

Что о SELECT CAST(CASt(GETDATE() AS int) AS DATETIME)??