我正在使用CTE生成一系列日期。
12/02/2010 10:00:00 12/02/2010 10:59:59
12/02/2010 11:00:00 12/02/2010 11:59:59
12/02/2010 12:00:00 12/02/2010 12:59:59
然后我将其加入到包含大量日期的索引视图中。
我有两个日期范围计数选项
1)我会对SUM(case)测试log_date以测试它是否在开始和结束日期之间,+ 1表示true,0表示false - 所以如果没有结果我将总是得到'0'
12/02/2010 10:00:00 12/02/2010 10:59:59 0
12/02/2010 11:00:00 12/02/2010 11:59:59 1
12/02/2010 12:00:00 12/02/2010 12:59:59 0
2)我可以使用每个日期范围的WHERE子句计算(*)。
12/02/2010 11:00:00 12/02/2010 11:59:59 1
正如您所期望的那样1)是有效的但是在性能上有很大的开销2)可能会有8000%的效率但如果应用了一个在指定日期范围之间返回null结果的过滤器,则无法返回范围。
有没有办法使用efficent WHERE子句但保留日期范围行详细说明'0'?
这里是案例解决方案的一些SQL:
SELECT [LABEL], [Display Start Date], [Display End Date],
SUM(CASE WHEN ([LOG].line_date BETWEEN [Start Date] AND [End Date]) THEN 1 ELSE 0 END) AS [Total Calls],
SUM(CASE WHEN ([LOG].line_date BETWEEN [Start Date] AND [End Date]) AND ([LOG].line_result = 1) THEN 1 ELSE 0 END) AS [1 Calls],
FROM [DATE RANGE FUNCTION] LEFT JOIN
dbo.vCallLog WITH (noexpand) as [LOG] on 0 > -1
GROUP BY [Start Date], [End Date], [Display Start Date], [Display End Date], [LABEL]
这是WHERE解决方案的一些SQL:
SELECT [LABEL], [Display Start Date], [Display End Date],
COUNT(dbo.vCallLog.line_id) AS [Total Calls],
SUM(CASE WHEN ([LOG].line_result = 1) THEN 1 ELSE 0 END) AS [1 Calls],
FROM [DATE RANGE FUNCTION] LEFT JOIN
dbo.vCallLog WITH (noexpand) as [LOG] on 0> -1
WHERE ([LOG].line_date BETWEEN [Start Date] AND [End Date])
GROUP BY [Start Date], [End Date], [Display Start Date], [Display End Date], [LABEL]
答案 0 :(得分:2)
好的,一点点pokery,我意识到我为自己做了一个小问题:
问题是WHERE子句及其对COUNT子句的位置。如果我正在使用WHERE&依靠相同的结果集,然后在日期之间我没有得到任何零行。但是,我计算所有内容并从同一结果集中省略WHERE并将WHERE子句放在JOIN 即[x]左连接中(从[b]中选择[a],其中[a]位于@x和amp之间; @y)作为[c] 我返回所有行,计数然后逐字计数。
我认为问题是WHERE子句先前省略了count选择,因为没有采取任何行动(根据编译器)
答案 1 :(得分:1)
如果我理解你,你可以试试
DECLARE @DateRanges TABLE(
StartDate DATETIME,
EndDate DATETIME
)
INSERT INTO @DateRanges (StartDate,EndDate) SELECT '12/02/2010 10:00:00','12/02/2010 10:59:59'
INSERT INTO @DateRanges (StartDate,EndDate) SELECT '12/02/2010 11:00:00','12/02/2010 11:59:59'
INSERT INTO @DateRanges (StartDate,EndDate) SELECT '12/02/2010 12:00:00','12/02/2010 12:59:59'
DECLARE @DateValues TABLE(
DateVal DATETIME
)
INSERT INTO @DateValues (DateVal) SELECT '12/02/2010 11:00:00'
INSERT INTO @DateValues (DateVal) SELECT '12/02/2010 11:01:00'
INSERT INTO @DateValues (DateVal) SELECT '12/02/2010 12:01:00'
SELECT t.StartDate,
t.EndDate,
COUNT(tv.DateVal) CountVal
FROM @DateRanges t LEFT JOIN
@DateValues tv ON tv.DateVal BETWEEN t.StartDate AND t.EndDate
GROUP BY t.StartDate,
t.EndDate
输出
StartDate EndDate CountVal
----------------------- ----------------------- -----------
2010-12-02 10:00:00.000 2010-12-02 10:59:59.000 0
2010-12-02 11:00:00.000 2010-12-02 11:59:59.000 2
2010-12-02 12:00:00.000 2010-12-02 12:59:59.000 1
答案 2 :(得分:0)
WHERE (<Condition based on rightHandTable.Column> OR rightHandTable.Column IS NULL)
当你有条件的化合物时,将尾随OR语句放在parens中也是个好主意:
WHERE a=1 AND b=1 OR b iS NULL
当a和b = 1或b为空时
,此结果为真与
不同WHERE a=1 AND (b=1 OR b is NULL)
这意味着必须为1且b必须为1或null