我正在为我的客户创建一个图表,他们想要在24小时,3天,1周,1个月等期间获得总客户数。老实说,我不是最好的SQL,所以产生这些查询不是我的强项。
关于让客户超过24小时,我遇到了两个可能有用的“where”陈述,但我不确定哪个是最好的。
第一个版本:
WHERE DATEDIFF(hh,CreatedDate,GETDATE())>24
第二版:
WHERE CreatedDate >= DATEADD(HH, -24, GETDATE())
第一个版本生成21行,第二个生成17行(当然来自同一个数据集),所以很明显一个比另一个更精确。我倾向于第一个,但我想你的意见......拜托。
谢谢, 安德鲁
答案 0 :(得分:10)
第一个版本不准确。
WHERE DateDiff(hh, CreatedDate, GETDATE()) > 24
这将返回23.0001小时前至24.9999小时之间的值,因为您计算的是“越过边界”,而不是实际的24小时。请注意,从1:59:59
到2:00:00
只有一秒钟,但DateDiff
小时将返回1小时。同样地,1:00:00
到2:59:59
差不多2小时,但DateDiff
小时返回相同的1小时。
第二个版本是正确的。
WHERE CreatedDate >= DateAdd(hh, -24, GETDATE())
在当前日期添加24小时将产生恰好24.0小时前的时间,达到毫秒。这将返回24小时的数据。
此外,即使它是您想要的,第一个版本也会很糟糕,因为引擎必须在整个表中的每一行上执行日期数学运算,这使得任何潜在的索引都无用并消耗了大量不必要的CPU。相反,在列名称的表达式的另一侧进行数学运算。复制第一个表达式的逻辑而没有性能损失将如下所示:
WHERE CreateDate >= DateAdd(hh, DateDiff(hh, 0, GETDATE()) - 24, 0)
示例:
GetDate() = '20100720 17:52'
DateDiff(hh, 0, '20100720 17:52') = 969065
DateAdd(hh, 969065 - 24, 0) = '20100719 17:00'
并证明这与你的第一个表达式相同:
DateDiff(hh, '20100719 17:00', '20100720 17:52') = 24
答案 1 :(得分:9)
避免使用第一个版本。首先,因为它禁用了索引利用率。第一个版本的第二个(功能)问题是,DATEDIFF(HOUR...)
返回的所有值小于25小时。为清楚起见,请尝试以下方法:
SELECT DATEDIFF(HOUR, '2010-07-19 00:00:00', '2010-07-20 00:59:59.99')
答案 2 :(得分:0)
对于你的每个where子句,也许这些?
WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(hh, -24, GETDATE)
WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(day, -3, GETDATE)
WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(wk, -1, GETDATE)
WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(mm, -1, GETDATE)
正如flo提到索引一样,只需确保您正在为CreatedDate列编制索引。