SQL 2012返回计数和两次之间的总和

时间:2016-02-25 17:15:10

标签: sql sql-server tsql sql-server-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

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

1 个答案:

答案 0 :(得分: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