Який найкращий спосіб урізати значення дати (як видалити години та секунди) у SQL Server 2008?
Наприклад:
declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)
-----------------------
2009-05-28 00:00:00.000
Який найкращий спосіб урізати значення дати (як видалити години та секунди) у SQL Server 2008?
Наприклад:
declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)
-----------------------
2009-05-28 00:00:00.000
Відповіді:
Це продовжує часто збирати додаткові голоси навіть через кілька років, і тому мені потрібно оновити його на сучасні версії Sql Server. Для Sql Server 2008 та новіших версій це просто:
cast(getDate() As Date)
Зауважте, що останні три абзаци внизу все ще застосовуються, і вам часто потрібно зробити крок назад і знайти спосіб уникнути першочергового складу.
Але є й інші способи досягти цього. Ось найпоширеніші.
Правильний шлях (новий з часу Sql Server 2008):
cast(getdate() As Date)
Правильний спосіб (старий):
dateadd(dd, datediff(dd,0, getDate()), 0)
Зараз це вже старше, але це все-таки варто знати, оскільки воно також може легко адаптуватися до інших часових моментів, наприклад, першого моменту місяця, хвилини, години чи року.
Цей правильний спосіб використовує документально підтверджені функції, що входять до стандарту ansi і гарантовано працюють, але це може бути дещо повільніше. Він працює, визначаючи, скільки днів проходить від 0 до поточного дня, і додає, що багато днів назад до дня 0. Він буде працювати незалежно від того, як зберігається час вашої дати та незалежно від того, який ваш місцеположення.
Швидкий шлях:
cast(floor(cast(getdate() as float)) as datetime)
Це працює, тому що стовпці дати зберігаються у вигляді 8-байтних бінарних значень. Закиньте їх плаваючими, підлогу, щоб видалити дріб, і часова частина значень пішла, коли ви повертаєте їх до дату. Це все просто біт зміщення без складної логіки, і це дуже швидко.
Зауважте, що це покладається на деталі впровадження, які Microsoft може вільно змінити в будь-який час, навіть в автоматичному оновленні служби Це також не дуже портативно. На практиці дуже малоймовірно, що ця реалізація незабаром зміниться, але все ж важливо усвідомлювати небезпеку, якщо ви вирішите її використовувати. А тепер, коли у нас є можливість зняти участь як побачення, це рідко буває необхідно.
Невірний шлях:
cast(convert(char(11), getdate(), 113) as datetime)
Неправильний спосіб працює шляхом перетворення в рядок, обрізання рядка та перетворення назад у дату. Це неправильно з двох причин: 1) це може працювати не у всіх локалях, і 2) мова йде про найповільніший можливий спосіб зробити це ... і не лише трохи; це як на порядок або на два повільніше, ніж інші варіанти.
Оновлення Це останнім часом отримує голоси, і тому я хочу додати, що, оскільки я опублікував це, я побачив досить вагомі докази того, що сервер Sql оптимізує різницю між продуктивністю між "правильним" та "швидким" способом. , значить, вам зараз слід віддавати перевагу першому.
У будь-якому випадку ви хочете написати свої запити, щоб уникнути необхідності робити це в першу чергу . Дуже рідко слід виконувати цю роботу над базою даних.
У більшості місць база даних вже є вашим вузьким місцем. Як правило, це найдорожчий сервер для додавання апаратного забезпечення для покращення продуктивності, а найскладніший для правильного встановлення цих доповнень (наприклад, ви повинні врівноважити диски з пам'яттю). Це також найважче масштабувати зовні, як технічно, так і з точки зору бізнесу; технічно набагато простіше додати веб-сервер або сервер додатків, ніж сервер баз даних, і навіть якщо це було помилково, ви не платите $ 20000 + за ліцензію сервера за IIS або apache.
Я намагаюся зробити так, що коли це можливо, ви повинні виконувати цю роботу на рівні програми. Тільки раз , коли ви коли - небудь знайти собі усічення DateTime на Sql Server, коли вам потрібно згрупувати в день, і навіть тоді , ймовірно , ви повинні мати додатковий набір стовпців як обчислюється стовпчика, підтримується під час вставки / оновлення або технічне обслуговування в логіці програми. Отримайте цю роботу з індексами, важкі для процесора ваші бази даних.
cast(getdate() as date)
?
getdate()
Тут ви знайдете резервне джерело для будь-якого джерела дати.
Лише для SQL Server 2008
CAST(@SomeDateTime AS Date)
Потім поверніть його до дату, якщо хочете
CAST(CAST(@SomeDateTime AS Date) As datetime)
Просто заради більш повної відповіді, ось робочий спосіб обрізання будь-якої з частин дати вниз, включаючи хвилини (замінити GETDATE()
датою для врізання).
Це відрізняється від прийнятої відповіді тим, що ви можете використовувати не тільки dd
(дні), а й будь-яку частину дати (див. Тут ):
dateadd(minute, datediff(minute, 0, GETDATE()), 0)
Зауважте, що у вислові вище значення 0
є постійною датою на початок року (1900-01-01). Якщо вам потрібно скоротити до менших частин, наприклад, до секунд або мілісекунд, вам потрібно взяти постійну дату, яка ближче до дати, яка буде усічена, щоб уникнути переповнення.
dateadd(minute, datediff(minute, 0, GETDATE()) / 15 * 15, 0)
Фрагмент, який я знайшов в Інтернеті, коли мені довелося це зробити:
dateadd(dd,0, datediff(dd,0, YOURDATE))
e.g.
dateadd(dd,0, datediff(dd,0, getDate()))
DateAdd(dd, DateDiff(...), 0)
. Це може вкусити вас, якщо ви не будете обережні.
У SQl 2005 ваша функція trunc_date може бути записана так.
(1)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END
Перший спосіб набагато чистіший. Він використовує лише 3 виклики методу, включаючи остаточний CAST () і не виконує з'єднання рядків, що є автоматичним плюсом. Крім того, тут немає величезних ролей. Якщо ви можете уявити, що позначки дати / часу можуть бути представлені, то перетворення від дати до чисел і назад до дат - це досить простий процес.
(2)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CONVERT(varchar, @date,112)
END
Якщо ви стурбовані впровадженням даними (2) або (3) мікрософт, це може бути нормально.
(3)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END
По-третє, більш багатослівний метод. Для цього потрібно розбити дату на частини року, місяця та дня, скласти їх у форматі "рр-р / мм / дд", а потім повернути їх до дати. Цей метод включає 7 викликів методів, включаючи остаточний CAST (), не кажучи вже про об'єднання рядків.
вибрати cast (floor (cast (getdate () як float)) як datetime) Посилайтеся на це: http://microsoftmiles.blogspot.com/2006/11/remove-time-from-datetime-in-sql-server.html
Для тих із вас, хто завітав сюди, шукаючи спосіб обрізати поле DATETIME до чогось меншого, ніж цілий день, наприклад, щохвилини, ви можете використовувати це:
SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)
тож якби сьогодні це було, 2010-11-26 14:54:43.123
то це повернеться2010-11-26 14:54:00.000
.
Щоб змінити інтервал, на який він посилається, замініть 1440,0 на кількість інтервалів у день, наприклад:
24hrs = 24.0 (for every hour)
24hrs / 0.5hrs = 48.0 (for every half hour)
24hrs / (1/60) = 1440.0 (for every minute)
(Завжди ставимо .0
на кінець, щоб неявно відкинути поплавок.)
Для тих з вас , цікаво , що (3.0/86400000)
це і в моєму розрахунку, SQL Server 2005 , здається, не гіпс від FLOAT
до DATETIME
точно, так що це додає 3 мілісекунди до того статі його.
datetime2
типом даних.
Цей запит повинен дати вам результат, еквівалентний trunc(sysdate)
в Oracle.
SELECT *
FROM your_table
WHERE CONVERT(varchar(12), your_column_name, 101)
= CONVERT(varchar(12), GETDATE(), 101)
Сподіваюсь, це допомагає!
Ви також можете витягнути дату using Substring
зі змінної datetime, а передача назад до datetime ігнорує частину часу.
declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime)
Крім того, ви можете отримати доступ до частин змінної datetime і об'єднати їх з усіченою датою конструкції, приблизно так:
SELECT cast(DATENAME(year, @Somedate) + '-' +
Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
DATENAME(day, @Somedate)
as datetime)
ви могли просто зробити це (SQL 2008):
оголосити @SomeDate date = getdate ()
select @SomeDate
28.05.2009
TRUNC (aDate, 'DD') уріже хв, сек та год
SRC: http://www.techonthenet.com/oracle/functions/trunc_date.php