У MS SQL 2000 та 2005, давши час, наприклад „2008-09-25 12:34:56”, який найефективніший спосіб отримати час, що містить лише „2008-09-25”?
Дублюється тут .
У MS SQL 2000 та 2005, давши час, наприклад „2008-09-25 12:34:56”, який найефективніший спосіб отримати час, що містить лише „2008-09-25”?
Дублюється тут .
Відповіді:
Я повинен визнати, що я раніше не бачив перетворення підлоги з поплавком, показано Меттом. Мені довелося це перевірити.
Я протестував чистий вибір (який поверне дату і час, а не те, що ми хочемо), правильне рішення тут (floor-float), загальноприйнятий "наївний", згаданий тут (stringconvert) і той, про який я згадав тут використання (як я думав, це було найшвидше).
Я перевірив запити на тестовому сервері MS SQL Server 2005, що працює на сервері Win 2003 SP2 із процесором Xeon 3 ГГц, що працює на максимальній пам’яті (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, лобічне логічне читання 0, лобове фізичне читання 0, лобове читання 0 читає
Час виконання SQL Server: час процесора = 422 мс, минулий час = 33803 мс.
(1000000 рядків (рядків)) Таблиця 'tblMeasureLogv2'. Кількість сканування 1, логічне читання 4752, фізичне читання 0, читання вперед читає 0, лобічне логічне читання 0, лобове фізичне читання 0, лобове читання 0 читає
Час виконання SQL Server: час процесора = 625 мс, минулий час = 33545 мс.
(1000000 рядків (рядків)) Таблиця 'tblMeasureLogv2'. Кількість сканування 1, логічне читання 4752, фізичне читання 0, читання вперед читає 0, лобічне логічне читання 0, лобове фізичне читання 0, лобове читання 0 читає
Час виконання SQL Server: час процесора = 1953 мс, минулий час = 33843 мс.
(1000000 рядків (рядків)) Таблиця 'tblMeasureLogv2'. Кількість сканування 1, логічне читання 4752, фізичне читання 0, читання вперед читає 0, лобічне логічне читання 0, лобове фізичне читання 0, лобове читання 0 читає
Час виконання SQL Server: час процесора = 531 мс, минулий час = 33440 мс. Час аналізу та компіляції SQL Server: час процесора = 0 мс, минулий час = 1 мс.
Час виконання SQL Server: час процесора = 0 мс, минулий час = 1 мс.
Що ми тут бачимо?
Зупинимося на часі процесора (ми розглядаємо перетворення), і ми бачимо, що маємо такі цифри:
Pure-Select: 422
Floor-cast: 625
String-conv: 1953
DateAdd: 531
З цього мені здається, що DateAdd (принаймні в цьому конкретному випадку) трохи швидший, ніж метод лиття підлоги.
Перш ніж ви поїдете туди, я провів цей тест кілька разів, змінивши порядок запитів, однакові результати.
Це щось дивне на моєму сервері, чи що?
Select DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)
DateDiff (Day, 0, GetDate ()) те саме, що DateDiff (Day, '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 року, ви отримаєте повідомлення про помилку.
Різниця двох стовпців дати та часу спричинила переповнення під час виконання.
Ви можете обійти цю помилку, використовуючи іншу контрольну дату (наприклад, 1 січня 2000 р.).
select cast(floor(cast(@datetime as float)) as datetime)
Працює, оскільки приведення дати до плаваючого дає кількість днів (включаючи частки дня) з 1 січня 1900 року. Підлогою він видаляє дробові дні і залишає кількість цілих днів, які потім можна повернути до дати.
у SQL Server 2012 використання
select cast(getdate() as date)
dateтип даних.
select cast(getdate()as varchar(11))as datetime
Щоб отримати РРРР-ММ-ДД, використовуйте:
select convert(varchar(10), getdate(), 120)
Змінити: На жаль, він хоче DateTime замість рядка. Еквівалент TRUNC () в Oracle. Ви можете взяти те, що я опублікував, і повернути назад до DateTime:
select convert(datetime, convert(varchar(10), getdate(), 120) , 120)
CONVERT, FLOOR і DATEDIFF будуть виконувати однаково.
Три методи описані в посиланні нижче. Я не перевіряв їх, щоб визначити, який найшвидший.
CAST(FLOOR(CAST(yourdate AS DECIMAL(12, 5))) AS DATETIME)виконує найкращі на сьогоднішній день. Ви можете побачити докази та тести при отриманні дати без часу на сервері sql
Що про SELECT CAST(CASt(GETDATE() AS int) AS DATETIME)??
CONVERT(VARCHAR(10), GETDATE(), 120) AS [YYYY-MM-DD]