我不明白这些是如何运作的,有人可以解释这些。
SELECT
P.ID,
P.CATEGORY_ID,
TIME = DATEADD(MINUTE, (DATEDIFF(MINUTE, 0, TIME) + 30) / 30 * 30, 0)
FROM
PRODUCTS P
WHERE
TIME >= CAST(CAST(DATEADD(DAY, - 15, GETUTCDATE()) AS DATE) AS DATETIME)
答案 0 :(得分:0)
我打算发表评论,但这可能比评论所能提供的文本更多。在分解您的查询的意图时:
,TIME = DATEADD(MINUTE, (DATEDIFF(MINUTE, 0, TIME) + 30) / 30 * 30, 0)
在这篇文章中,第二个TIME
将引用TIME
表中的PRODUCTS
列,但在DATEADD()
函数分配给TIME
时会被覆盖{1}}中的{1}}值。这是一种不好的做法,并且会像查询中那样覆盖实际的列值。 SELECT
应该有所不同,例如,TIME
。
从该声明的内部出发:
,TIME2
>>基本上,由于SQL中的DATEDIFF(MINUTE,0,TIME)
存储为自服务器的纪元以来的数字分钟数(即1/1/2018 = 62062590 =自1900年1月1日以来的分钟数),因此计算自分钟以来的分钟差异date
和TIME
或epoch
。 0
会返回DATEDIFF()
。
integer
>>由于DATEDIFF(MINUTE,0,TIME) + 30
函数为DATEDIFF()
分钟提供了integer
分钟,因此只需将该数字加30,即相当于TIME
之后的30分钟。
(....) / 30 * 30
>>然后奇怪的数学开始了。我认为它正在尝试将所有内容转换回integer
或其他东西。
DATEADD(MINUTE, (....), 0)
>>我们再次向先前计算的0
添加integer
分钟。由于DATEADD()
会返回date
个对象,因此很可能只是将所有内容转换回date
。
TIME = ......
>>我再次认为这是不好的做法。尽管名称在SQL中已经具有特殊含义,但查询表明TIME
已经是PRODUCTS
中的列。这只是在TIME
中创建SELECT
列并为其指定值。
然后我们转到查询的WHERE
部分:
WHERE TIME >= ...
>>这再次表明TIME
是PRODUCTS
中的一列。如上所述,如果TIME
应该是SELECT
的值,那么由于WHERE
早在SELECT
之前处理,它就无法工作。
(DATEADD(DAY,-15,GETUTCDATE())
>>这只是采用当前的UTC日期(GETUTCDATE()
)并从中减去15天。
其余部分只是将日期对象转换回datetime
对象。
然后检查TIME
是否比今天之前的15天更近。