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

SQL 2012返回计数和两次之间的总和,sql,sql-server,tsql,sql-server-2012,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(DATETIM

我以前问过这个问题,我取得了一些进展。现在我需要一个更严格的数据集,但是我的代码有问题。以下是我正在使用的:

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)

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

我可以建议您忘记使用递归来实现您的目标吗,因为这不会执行,而且您似乎已经有了问题

对于你现在所做的,我会选择一个

下面是使用理货表翻译的脚本。这将执行得更好,同时,它可能会解决您的问题,也可能不会解决您的问题,但如果问题仍然存在,您肯定会了解更多

;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

此外,示例数据只是采样,而不是我的实际结果。不要担心日期,除了看到StartTime扫描之间存在间隙之外,您可以添加一个Order by,并检查它是否真的没有显示所有间隔或只是无序?您是否有意在@maxdate上排除10分钟间隔?请注意,当你可能想开始的时候,在我的脸上谈论鸡蛋@我相信你是对的。看起来有些结果参差不齐。ORDER BY似乎已经解决了这个问题。非常感谢你!就像@habo评论的那样,我确实用一个开始取代了中间,这是一个很好的信息,我非常感谢你的贡献。另外,我真的很喜欢你格式化代码的方式!眼睛很好看。然而,这一个运行了大约24.5秒,而另一个现在我已经开始工作了!在15秒左右。我不确定是什么原因造成了这种差异,但我现在就用另一种。再次感谢@博士,我的错,我刚刚重新阅读了你的代码,发现你的cte恰巧和一个收费表一模一样。此外,您的理货表创建了正确的日期,因此可以在联接中使用它。我的必须计算它,所以是的…很好!事实上,我发现结果在那里,只是没有顺序。因此,添加一个ORDERBY子句修复了它。啊…很抱歉浪费了你的时间,伙计。
;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