SQL 服务器 2012/2014 计算 运行 计数

SQL Server 2012/2014 Calculate running count

我正在尝试创建一个查询,它将 return 运行 按日期计数,按模块分组。

我感兴趣的 table 字段是 DateID、模块。 Module 和 DateID 存在一行这一事实表明计数为 1。一个模块可以针对单个 DateID 出现多次,显然每天也有多个模块。 运行 以下查询几乎 return 是我想要的:

SELECT 
    DateID,
    Module,
    ROW_NUMBER() OVER (PARTITION BY Module ORDER BY DateID) [RunningCount]
FROM dbo.vwFiles
WHERE DateID IN (5467,5468)
AND Module IN ('PC','DD','NL')
ORDER BY DateID

    DateID  Module  RunningCount
    5467    DD      1
    5467    DD      2
    5467    DD      3
    5467    NL      1
    5467    NL      2
    5467    NL      3
    5467    NL      4
    5467    PC      1
    5467    PC      2
    5467    PC      3
    5468    NL      5

但是,我不仅获得每个 DateID 的单个计数,我还获得每个 DateID 上每个模块记录的计数。

修改查询如下:

SELECT DateID, Module,MAX(RunningCount) RunningCount
FROM 
(
    SELECT DateID, Module
    , ROW_NUMBER() OVER(PARTITION BY Module ORDER BY DateID) RunningCount
    FROM vwFiles
    WHERE DateID IN (5467,5468)
    AND Module IN ('PC','DD','NL')  
) z
GROUP BY Module, DateID
ORDER BY DateID, Module

    DateID  Module  RunningCount
    5467    DD      3
    5467    NL      4
    5467    PC      3
    5468    NL      5

确实给了我想要的。不过我还以为有更简单的方法呢?

运行 总计是如此自然的事情,几乎令人惊讶的是没有一些本地方法来做到这一点。这是一种不同的方法,我认为它更简单一些,但我也认为 'simple' 可能是一个非常主观的术语 :)

declare @t table (DateId int, Module char(2))

insert @t values (5467, 'DD'),
                 (5467, 'DD'),
                 (5467, 'DD'),
                 (5467, 'NL'),
                 (5467, 'NL'),
                 (5467, 'NL'),
                 (5467, 'NL'),
                 (5467, 'PC'),
                 (5467, 'PC'),
                 (5467, 'PC'),
                 (5468, 'NL')

; with cte as (
    select
        row_number() over (order by DateId, Module) as rn,
        t.*
    from 
        @t t
)
SELECT
    t1.DateId,
    t1.Module,
    count(distinct t2.rn)
FROM
    cte AS t1
        LEFT JOIN cte AS t2 ON t2.Module = t1.Module and t2.rn <= t1.rn
GROUP BY 
    t1.DateId, 
    t1.Module
ORDER BY 
    t1.DateId,
    t1.Module

Aaron Bertrand 在 SQLPerformance.com Best approaches for running totals 上发表了一篇相当不错的文章 - 值得一读。

你所做的根本不是 "running total"。您只是按组计数。所以,你可以简单地做那个操作:

SELECT DateId, Module, COUNT(*) FROM vwFiles
GROUP BY DateId,Module

问题不在于你面对的是一个复杂的问题,而是你面对它的方式不对。