怎么写一个总是返回上周一到上周日数据的sql语句?任何指导表示赞赏。
谢谢。
最佳答案
t-clausen.dk's answer确实有效,但可能不清楚 为什么它有效(对您和跟随您的开发人员都无效)。由于增加清晰度有时会以牺牲简洁性和性能为代价,我想解释为什么它可以工作,以防您更喜欢使用更短的语法。
SELECT t.*
FROM <table> t CROSS JOIN
(SELECT DATEDIFF(day, 0, getdate() - DATEDIFF(day, 0, getdate()) %7) lastmonday) a
WHERE t.yourdate >= a.lastmonday - 7 and yourdate < a.lastmonday
SQL Server 如何存储 datetime
内部SQL Server 存储
datetime
作为两个 4 字节整数;前四个字节表示自 1/1/1900(或 1/1/1900 之前,对于负数)以来的天数,后四个字节表示自午夜以来的毫秒数。使用
datetime
与 int
或 decimal
因为 datetime
存储为两个 4 字节整数,在 T-SQL 中很容易在数字和日期数据类型之间移动。例如,SELECT GETDATE() + 1
返回相同的 SELECT DATEADD(day, 1, GETDATE())
, 和 CAST(40777.44281 AS datetime)
与 2011-08-24 10:37:38.783
相同.1/1/1900
如上所述,由于日期时间的第一个整数部分是自 1900 年 1 月 1 日(也称为 SQL Server 纪元)以来的天数,
CAST(0 as datetime)
根据定义相当于1900-01-01 00:00:00
DATEDIFF(天,0,GETDATE())这就是事情开始变得既棘手又有趣的地方。首先,我们已经确定,当
0
被视为日期,与 1/1/1900 相同,所以 DATEDIFF(day, '1/1/1900', GETDATE())
与 DATEDIFF(day, 0, GETDATE())
相同— 两者都将返回自 1/1/1900 以来的当前天数。但是,等等:当前的天数正是日期时间的前四个字节所表示的天数!在单个语句中,我们做了两件事:1) 我们删除了 GETDATE()
返回的“时间”部分。并且我们有一个整数值,我们可以使用它来使查找最近的星期日和前一个星期一的计算更容易一些。星期一的模 7
DATEDIFF(day, 0, GETDATE()) % 7
利用 DATEPART(day, 0)
的事实(冒着过分强调这一点的风险,它与 DATEPART(day, '1/1/1900')
相同)返回 2
(周一)。 1 因此,DATEDIFF(day, 0, GETDATE()) % 7
将始终产生当前日期从星期一开始的天数。1 除非您使用
DATEFIRST
更改了默认行为.最近的星期一
对于它自己的标题来说几乎太微不足道了,但在这一点上,我们可以把到目前为止我们所拥有的一切放在一起:
GETDATE() - DATEDIFF(day, 0, GETDATE()) %7
给你最近的星期一 DATEDIFF(day, 0, GETDATE() - DATEDIFF(day, 0, GETDATE()) %7)
为您提供最近的星期一作为整个日期,没有时间部分。 但是海报想要从周一到周日的一切......
发布的答案没有使用包含在内的 BETWEEN 运算符,而是排除了最后一天,因此无需进行任何移动或计算即可获得正确的日期范围:
t.yourdate >= a.lastmonday - 7
返回日期自(或包括)最近第二个星期一午夜开始的记录 t.yourdate < a.lastmonday
返回日期早于(但不包括)最近星期一午夜的记录。 我强烈支持编写易于理解的代码,无论是对您还是一年后跟随您的开发人员(也可能是您)。我相信我之前发布的答案即使对于新手 T-SQL 程序员也应该是可以理解的。但是,t-clausen.dk 的回答简洁,性能好,在生产代码中可能会遇到,所以我想给出一些解释,以帮助 future 的访问者理解它的工作原理。
关于tsql - 始终返回上周周一至周日的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7153687/