Округление даты и времени SQL до полуночи


81

У меня небольшая проблема с моим SQL-запросом. Я использую функцию GETDATE, однако, скажем, я выполняю сценарий в 17:00, он будет извлекать записи с 17.12.2011 до 17.12.2011. Как сделать так, чтобы он подтягивал записи за весь 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
Бассам Механни

@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)

Это не округление, это усечение ... Но я думаю, что это то, о чем спрашивают. (Чтобы округлить, добавьте единицу и усеките ... и это тоже не округление, это потолок, но опять же, скорее всего, что вы хотите. Чтобы действительно округлить, добавьте 0,5 (это работает?) И усеките.

Оказывается, вы можете добавить 0,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()

Результат: 2012-12-14 16: 03: 33.360

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

Результат 2012-12-15 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

Это может показаться дешевым, но у меня это работает

ВЫБРАТЬ ПРЕОБРАЗОВАТЬ (ДАТА ВРЕМЕНИ, ВЛЕВО (ПРЕОБРАЗОВАТЬ (ВАРЧАР, @ dateFieldOrVariable, 101), 10) + '00: 00: 00.000')


1

Вы можете преобразовать datetime в дату, а затем обратно в datetime. Это сбросит метку времени.

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

выберите приведение (cast (GETDATE () as date) as datetime) --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 способность Оптимизатора к показателям использования и т.д. Использованием функций Строковых сделать даты арифметика и сравнение является очень плохой идеей. Об этом не следует даже упоминать, это такой плохой вариант.
MatBailie,

Вам не обязательно, если вы используете SQL Server 2008, иначе я не уверен, как еще вы могли бы сделать это в SQL Server 2000/2005, пример был бы признателен, спасибо.
Бассам Механни

Чтобы быть справедливым. Оба варианта лишают оптимизатора возможности использовать индексы. Вы должны выполнить и функциональные возможности столбца предиката фильтра. Это включает броски.
ПИМ

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.