SQL2008年累计计数

SQL 2008 cumulative count

我有一个返回按日期分组的行数的查询:

SELECT  convert(date, run.TimeStamp) as TimeStamp, count(*)
FROM  ScriptResult AS res INNER JOIN
    ScriptRun AS run ON run.ScriptRunID = res.ScriptRunID INNER JOIN
    WorkListItems AS wli ON wli.WorkListItemID = res.WorklistItemID INNER JOIN
    WorkList AS wl ON wl.WorkListID = wli.WorkListID
WHERE (wli.WorkListID = @WLID)
GROUP by convert(date, run.TimeStamp)
ORDER BY convert(date, run.TimeStamp);

这会产生如下结果集:

TimeStamp   (ItemCount)
2015-03-10  5364
2015-03-11  22027
2015-03-12  18037

现在我想要的是累计汇总itemcount,像这样:

TimeStamp   ItemCount   TotalCount
2015-03-10  5364    5364
2015 -03-11 22027   27391
2015-03-12  18037   45428

查询需要兼容2008R2。 我玩过 [count ...over..partition by] 的几种变体,但问题是 window 函数边界应该改变。而且我不能使用 ROWS 或 RANGE。

有什么想法吗? 提前致谢。

您可以尝试创建一个临时 table 来保存您可以进一步聚合到 return ItemCount 字段上的累计总和的第一个查询结果:

CREATE TABLE #TempTable(
    [SeqNo] [int] NULL,
    [TimeStamp] [Date] NULL,
    [ItemCount] [int] NULL     
) ON [PRIMARY]

SELECT
    ROW_NUMBER() OVER (PARTITION BY res.ScriptRunID ORDER BY run.TimeStamp) AS SeqNo,
    CONVERT(Date, run.TimeStamp) AS TimeStamp, 
    COUNT(*) AS ItemCount
INTO #TempTable
FROM ScriptResult AS res 
INNER JOIN ScriptRun AS run 
    ON run.ScriptRunID = res.ScriptRunID 
INNER JOIN WorkListItems AS wli 
    ON wli.WorkListItemID = res.WorklistItemID 
INNER JOIN  WorkList AS wl 
    ON wl.WorkListID = wli.WorkListID
WHERE (wli.WorkListID = @WLID)
GROUP BY CONVERT(Date, run.TimeStamp)
ORDER BY CONVERT(Date, run.TimeStamp);

SELECT 
     t1.TimeStamp, 
     t1.ItemCount, 
     SUM(t2.ItemCount) AS TotalCount
FROM #TempTable AS t1
INNER JOIN #TempTable AS t2 
    on t1.SeqNo >= t2.SeqNo 
GROUP BY t1.TimeStamp, t1.ItemCount
ORDER BY t1.TimeStamp

SQL Fiddle Example 注意:这链接到 Microsoft SQL Server 2014 数据库版本 SQL fiddle,它也应该与 SQL Server 2008 一起使用。

尝试使用相关子查询:

;WITH cte as(
               SELECT  convert(date, run.TimeStamp) as TimeStamp, count(*) AS S
               FROM  ScriptResult AS res INNER JOIN
                     ScriptRun AS run ON run.ScriptRunID = res.ScriptRunID INNER JOIN
                     WorkListItems AS wli ON wli.WorkListItemID = res.WorklistItemID INNER JOIN
                     WorkList AS wl ON wl.WorkListID = wli.WorkListID
               WHERE (wli.WorkListID = @WLID)
               GROUP by convert(date, run.TimeStamp)
)
SELECT TimeStamp, 
       S, 
       (SELECT SUM(S) FROM cte t2 WHERE t2.TimeStamp <= t1.TimeStamp) AS TS  
FROM cte  t1