将SQL DateTime舍入为午夜


81

我的SQL查询有一个小问题。我正在使用GETDATE函数,但是,假设我在下午5点执行脚本,它将在12/12/2011 5PM到12/18/2011 5PM之间提取记录。我怎样才能使整个12/12/2011的记录都拉起来-12/18/2011基本忽略时间。

我的剧本:

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

Answers:


114

在SQL Server 2008及更高版本中,您可以将强制DateTime转换为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
我得到这个Type日期不是一个定义的系统类型。
henryaaron 2011年

2
我猜您当时不使用SQL 2008 :)
DaveShaw 2011年

@ user1090389这就是为什么我放置字符串转换选项的原因; D
Bassam Mehanni 2011年

@DaveShaw-那里缺少DATEADD
MatBailie 2011年

抱歉@Dems Dave的看上去不太复杂
henryaaron 2011年

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

结果: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所述,您可以在SQL Server 2008及更高版本中强制转换为DATE。

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

第二个条件实际上可以是just 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

这看起来便宜,但对我有用

SELECT CONVERT(DATETIME,LEFT(CONVERT(VARCHAR,@ dateFieldOrVariable,101),10)+'00:00:00.000')


1

您可以将日期时间转换为日期,然后再转换为日期时间。这将重置时间戳。

选择getdate()--2020-05-05 13:53:35.863

选择演员表(cast(cast(GETDATE()as date)作为日期时间)--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
如果使用第一个示例,则会破坏优化器使用索引等的能力。使用String函数执行Date算术和比较是一个非常糟糕的主意。甚至不应该提及(imo),这是一个糟糕的选择。
MatBailie 2011年

如果您使用的是SQL Server 2008,则不必一定要这样做,否则,我不确定在SQL Server 2000/2005中还可以怎么做,谢谢您举个例子。
巴萨姆·汉尼

公平起见。这两种选择都会破坏优化器使用索引的能力。您应该在过滤谓词列上执行和功能。这包括演员。
pim

0

您可以舍入时间。

使用ROUND下方将把它向下舍入到午夜。

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >  CONVERT(datetime, (ROUND(convert(float, getdate()-6.5),0)))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.