这继续频繁地收集额外的选票,甚至几年后,所以我需要为现代版本的 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 Server 将优化两者之间的性能差异“正确”的方式和“快速”的方式,这意味着你现在应该倾向于前者。
在任何一种情况下,您都希望编写查询以避免一开始就需要这样做。您很少会在数据库上进行这项工作。
在大多数地方,数据库已经是您的瓶颈。通常,为提高性能而添加硬件最昂贵的服务器,以及最难正确添加硬件的服务器(例如,您必须平衡磁盘和内存)。从技术和商业角度来看,它也是最难向外扩展的;从技术上讲,添加 Web 或应用程序服务器比添加数据库服务器要容易得多,即使这是错误的,您也无需为 IIS 或 apache 的每个服务器许可证支付 20,000 美元以上。
我想说的是,只要有可能,您就应该在应用程序级别进行这项工作。 唯一你应该发现自己在 Sql Server 上截断日期时间的时间是你需要按天分组的时候,即使那样你也应该有一个额外的列设置为计算列,维护在插入/更新时间,或在应用程序逻辑中维护。从您的数据库中移除这个破坏索引、占用大量 CPU 资源的工作。