2016-02-25 44 views
0

我之前询问过这个查询,并且我取得了一些进展。现在我需要一个更受限制的数据集,但是我的代码存在问题。下面是我使用的是什么:SQL 2012返回次数和两次之间的总和

DECLARE @mindate DATETIME = '2011-12-30' 
DECLARE @maxdate DATETIME = '2011-12-31' 

;WITH cte 
AS (SELECT 
     CONVERT(DATETIME,@mindate) AS [StartDate], 
     DATEADD(MI, 10,CONVERT(DATETIME,@mindate)) AS [EndDate] 
    UNION ALL 
    SELECT 
     DATEADD(MI, 10, [StartDate]), 
     DATEADD(MI, 10, [EndDate]) 
    FROM cte 
    WHERE [StartDate] < CONVERT(DATETIME,@maxdate)) 

SELECT 
    [StartDate], 
    [EndDate], 
    COUNT(cr.MESSAGE_SIZE) AS [TransactionItemsMigrated], 
    SUM(cr.MESSAGE_SIZE) AS [TransactionSizeBytes], 
    (SELECT COUNT(*) FROM MESSAGE WHERE MESSAGE_STATUS = 2) [CurrentItemsFailed] 
FROM cte 
LEFT JOIN CROSS_REFERENCE cr 
    ON cr.MIGRATION_DATE_TIME BETWEEN [StartDate] AND [EndDate] 
GROUP BY cte.StartDate, cte.EndDate 
OPTION (MAXRECURSION 0) 

我需要显示一排,每10分钟,即使TransactionItemsMigrated和/或TransactionSizeBytes为0或NULL。我得到的结果不会每10分钟显示一次。 StartDate和EndDate之间的时间跨度显示正确,并且似乎正确计数了项目和大小,但StartDate正在跳跃超过10分钟。下面的每个条目都是一行。

StartDate 2016-02-01 00:40:00.000 
EndDate 2016-02-01 00:50:00.000 
TransactionItemsMigrated 1925 
TransactionSizeBytes 1843712 
CurrentItemsFailed 6538601 

StartDate 2016-02-01 01:50:00.000 
EndDate 2016-02-01 02:00:00.000 
TransactionItemsMigrated 1892 
TransactionSizeBytes 51712 
CurrentItemsFailed 6538601 

我无法粘贴结果,因为它在没有复制/粘贴访问权限的虚拟机上运行。有什么建议么?

+0

此外,示例数据只是取样,而不是我的实际结果。不要担心日期,除非看到StartTime的 –

+2

之间存在差距您可以通过添加订单并检查它是否真的没有显示所有间隔或只是无序吗? – mxix

+1

您是否有意在'@ maxdate'上排除10分钟的间隔?请注意,当您可能需要'start <= event HABO

回答

0

我可以建议你忘记使用递归来实现你的目标,因为这不会执行,你已经看起来有问题吗?我想用tally table去做。

这是您的脚本使用理货表的翻译。这将表现得更好,同时,它可能会或可能不会解决你的问题,但如果它仍然存在,你一定会对这个问题有更多的了解。

;WITH 
t1  AS (SELECT N = 1 UNION ALL SELECT 1 N), 
t2  AS (SELECT N = 1 FROM t1 x, t1 y), 
t3  AS (SELECT N = 1 FROM t2 x, t2 y), 
t4  AS (SELECT N = 1 FROM t3 x, t3 y), 
t5  AS (SELECT N = 1 FROM t4 x, t4 y), 
Tally AS (SELECT N = ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) 
      FROM t5 AS x, t5 as y)--building a tally with recursive but an less expensive one then the one you had. 

SET DATEFORMAT YMD 
DECLARE @mindate DATETIME = '2011-12-30' 
DECLARE @maxdate DATETIME = '2011-12-31' 
DECLARE @NMax INT 
SELECT @NMax = ISNULL(DATEDIFF(MINUTE, @mindate, @maxdate)/10, 0) --Count the number of 10 minutes slice between the two dates. 

SELECT [StartDate]     = DATEADD(MINUTE, (Tally.N - 1) * 10, @mindate), 
     [EndDate]     = DATEADD(MINUTE, (Tally.N) * 10, @mindate), 
     [TransactionItemsMigrated] = COUNT(cr.MESSAGE_SIZE), 
     [TransactionSizeBytes]  = SUM(cr.MESSAGE_SIZE), 
     [CurrentItemsFailed]  = (SELECT COUNT(*) FROM MESSAGE WHERE MESSAGE_STATUS = 2) 
FROM Tally 
LEFT JOIN CROSS_REFERENCE AS cr ON DATEADD(MINUTE, (Tally.N - 1) * 10, @mindate) >= cr.MIGRATION_DATE_TIME 
           AND DATEADD(MINUTE, (Tally.N) * 10, @mindate) < cr.MIGRATION_DATE_TIME 
WHERE Tally.N <= @NMax 
ORDER BY Tally.N 
+0

像@habo评论说的,我用Start <= eventDate AXMIM

+0

取代了BETWEEN这是个很好的信息,我非常感谢这个贡献。另外,我真的很喜欢你的代码格式!非常好的眼睛。然而,这一次花费了大约24.5秒的时间,另一个(现在我已经开始工作了!不知道是什么原因导致了这种差异,但我现在会和其他人一起去。再次感谢! –

+0

@doc,我不好,我只是重新读你的代码,看到你的cte碰巧就像一个TallyTable。此外,您的理货表建立了正确的日期,所以它可以在连接中使用。我必须计算它,所以是... – AXMIM