Округлення SQL DateTime до опівночі


81

У мене невелика проблема із моїм запитом SQL. Я використовую функцію GETDATE, однак, припустимо, я виконую скрипт о 17:00, він буде виводити записи між 12/12/2011 17:00 і 18/12/2011 17:00. Як я можу змусити його збирати записи протягом усього 12.12.2011 - 18.12.2011, в основному ігноруючи час.

Мій сценарій:

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate > (GETDATE()-6)  

Відповіді:


114

У SQL Server 2008 та новіших версіях ви можете DateTimeпередати файл a Date, який видаляє елемент часу.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= (cast(GETDATE()-6 as date))  

У SQL Server 2005 і нижче ви можете використовувати:

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= DateAdd(Day, Datediff(Day,0, GetDate() -6), 0)

1
Я зрозумів, що ця дата типу не є визначеним типом системи.
henryaaron

2
Я думаю, ви тоді не використовуєте SQL 2008 :)
DaveShaw

@ user1090389 ось чому я поставив опцію перетворення рядків; D
Bassam Mehanni

@DaveShaw - Відсутній DATEADD там
MatBailie

Вибачте @Dems Дейв виглядає менш складно
henryaaron

54

Ось найпростіша річ, яку я знайшов

-- Midnight floor of current date

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()))

DATEDIFF повертає ціле число днів до або після 1900-1-1, а Convert Datetime обов'язково повертає його до цієї дати опівночі.

Оскільки DateDiff повертає ціле число, ви можете використовувати додавання або віднімання днів, щоб отримати правильний зсув.

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()) + @dayOffset)

Це не округлення, це усічення ... Але я думаю, що про це просять. (Для округлення додайте одиницю та усікайте ... і це теж не округлення, а стеля, але знову ж, швидше за все, що ви хочете. Дійсно округлення додайте .5 (чи це працює?) Та усікайте.

Виявляється, ви можете додати .5 до GetDate (), і це працює, як очікувалося.

-- Round Current time to midnight today or midnight tomorrow

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE() + .5))

Я провів усі свої випробування на SQL Server 2008, але, думаю, ці функції стосуються і 2005 року.


Це працює в 2k5, щойно перевірено. where [ScanDate] >= convert(datetime, datediff(day, 0, getdate())) and [ScanDate] < convert(datetime, datediff(day, -1, getdate()))
nulltron

9
--
-- SQL DATEDIFF getting midnight time parts 
--
SELECT GETDATE() AS Now, 
   Convert(DateTime, DATEDIFF(DAY, 0, GETDATE())) AS MidnightToday,
   Convert(DateTime, DATEDIFF(DAY, -1, GETDATE())) AS MidnightNextDay,
   Convert(DateTime, DATEDIFF(DAY, 1, GETDATE())) AS MidnightYesterDay
go
Now                   MidnightToday          MidnightNextDay        MidnightYesterDay     
 --------------------  ---------------------  ---------------------  --------------------- 
 8/27/2014 4:30:22 PM  8/27/2014 12:00:00 AM  8/28/2014 12:00:00 AM  8/26/2014 12:00:00 AM 

5
SELECT getdate()

Результат: 14.12.2012 16: 03: 33.360

SELECT convert(datetime,convert(bigint, getdate()))

Результат 15.12.2012 00: 00: 00.000


1
Дякуємо за відгук. Те, що я намагався підкреслити, що перетворення на bigint і назад робить округлення за вас.
Джеремі Аткінсон,

1
Цей код округлює його до опівночі в кінці дня, якщо час після полудня, що спричиняє помилку протягом половини дня.
ChrisM

Використання цього методу може спричинити вплив на продуктивність пізніше із більшими наборами даних.
Taco タ コ ス

3

Як згадував @BassamMehanni, ви можете транслювати як DATE у SQL Server 2008 і далі ...

SELECT
  *
FROM
  yourTable
WHERE
      dateField >= CAST(GetDate() - 6 AS DATE)
  AND dateField <  CAST(GetDate() + 1 AS DATE)

Друга умова насправді може бути справедливою GetDate(), але я показую цей формат як приклад того, Less Than DateXщоб уникнути необхідності передавати dateField також у DATE, тим самим масово покращуючи продуктивність.


Якщо ви в 2005 році або менше, ви можете використовувати це ...

SELECT
  *
FROM
  yourTable
WHERE
      dateField >= DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) - 6, 0)
  AND dateField <  DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) + 1, 0)

3

Спробуйте скористатися цим.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= CONVERT(DATE, GETDATE())

1

Це може виглядати дешево, але для мене це працює

ВИБЕРІТЬ КОНВЕРТУРУ (ДАТАТИ, ВЛІВО (КОНВЕРТУВАТИ (VARCHAR, @ dateFieldOrVariable, 101), 10) + '00: 00: 00.000')


1

Ви можете перетворити дату на дату, а потім повернути на дату. Це скине позначку часу.

виберіть getdate () --2020-05-05 13: 53: 35.863

вибрати акторський склад (акторський склад (GETDATE () як дату) як дату та час) --2020-05-05 00: 00: 00.000

0

Я зазвичай це роблю

SELECT *
FROM MyTable
WHERE CONVERT(VARCHAR, MyTable.dateField, 101) = CONVERT(VARCHAR, GETDATE(), 101)

якщо ви використовуєте SQL SERVER 2008, ви можете це зробити

SELECT *
FROM MyTable
WHERE CAST(MyTable.dateField AS DATE) = CAST(GETDATE() AS DATE)

Сподіваюся, це допомагає


3
Якщо ви використовуєте перший приклад ви Destory здатність оптимізатора до показників використання і т.д. Використанням функцій строкового зробити дати арифметика і порівняння є дуже поганою ідеєю. Про це ніколи не слід (imo) навіть згадувати, це такий бідний варіант.
MatBailie

Вам не потрібно, якщо ви використовуєте SQL Server 2008, інакше, я не впевнений, як інакше ви могли це зробити в SQL Server 2000/2005, приклад буде вдячний, дякую.
Bassam Mehanni

Справедливості заради. Обидва варіанти руйнують можливість оптимізатора використовувати індекси. Ви повинні виконати та функціональність стовпця предикат фільтра. Сюди входять зліпки.
пім

0

Ви можете округлити час.

Використовуючи ROUNDнижче, округлятиме його до півночі.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >  CONVERT(datetime, (ROUND(convert(float, getdate()-6.5),0)))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.