基于列的累积 SUM

Cummulative SUM based on columns

我有一个 table 值如下:

我想根据 IDyear 获得累计总和,所以它应该 return 像这样的输出,即 id- 1 和 2010 年的记录总和将是 2。 id-2 和 2010 年的记录总和将为 1 并且 id- 2,对于 2011 年,它将是 1+1 = 2,即我需要 运行 每个 id 的总数,根据年份按升序排列。

同样对于 id =3 Sum 将为 1 ,对于 id 4 将基于年份为 1 。对于 5,2014 年将是 3,对于 2015 年,它将是前一年的计数总和 + 当前年度的计数总和,即 3 + 1 = 4,对于 2016 年,它将是 3+ 1+1 = 5。因此,要做什么。有人可以帮忙吗?

有很多方法可以做到这一点。这是其中之一,带有内部查询:

create table #table_name
(
    UserID int,
    Year int
)
INSERT INTO #table_name (UserID, Year)
VALUES
    (1, 2010)
    ,(1,2010)
    ,(2,2010)
    ,(2,2011)
    ,(3,2012)
    ,(4,2013)
    ,(5,2014)
    ,(5,2014)
    ,(5,2014)
    ,(5,2015)
    ,(5,2016)

SELECT 
    UserID
    ,YEAR
    ,(SELECT COUNT(Year) FROM #table_name WHERE Year <= tt.Year AND UserID = tt.UserID)
FROM 
    #table_name AS tt
GROUP BY UserID, Year

您也可以使用 row number over(编辑:请参阅下面有关此技术的答案,我认为对于这样一个简单的任务来说有点太复杂了)。上面的查询 returns 你需要的输出

+--------+------+-------+
| UserID | Year | COUNT |
+--------+------+-------+
|      1 | 2010 |     2 |
|      2 | 2010 |     1 |
|      2 | 2011 |     2 |
|      3 | 2012 |     1 |
|      4 | 2013 |     1 |
|      5 | 2014 |     3 |
|      5 | 2015 |     4 |
|      5 | 2016 |     5 |
+--------+------+-------+

这比我想要的嵌套更多,我觉得有更好的方法可以只用一个 windows 函数来做到这一点,但我无法避免没有唯一的数据行.

SELECT id,
year ,sum(c) OVER (
    PARTITION BY id ORDER BY year rows unbounded preceding
    )
FROM (
SELECT id,
    year,
    count(rn) c
FROM (
    SELECT id,
        year,
        row_number() OVER (
            ORDER BY year
            ) AS rn
    FROM your_table -- you will need to change this to your table
    ) a
GROUP BY id,
    year
) a

我们所做的是首先使用行号构建数据,所以现在一切都是唯一的,然后我们对那个唯一的行号进行计数并执行 windows 函数来执行 运行 总行数按年计算。

不需要让事情变得比他们需要的更复杂...

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    ID INT NOT NULL,
    [Year] INT NOT NULL 
    );
INSERT #TestData (ID, Year) VALUES
    (1, 2010), (1, 2010), (2, 2010), (2, 2011), 
    (3, 2012), (4, 2013), (5, 2014), (5, 2014),
    (5, 2014), (5, 2015), (5, 2016);

--=======================================

SELECT
    tdg.ID,
    tdg.Year,
    RunningCount = SUM(tdg.Cnt) OVER (PARTITION BY tdg.ID ORDER BY tdg.Year ROWS UNBOUNDED PRECEDING)
FROM (   
    SELECT td.ID, td.Year, Cnt = COUNT(1)
    FROM #TestData td
    GROUP BY td.ID, td.Year
    ) tdg;

结果...

ID          Year        RunningCount
----------- ----------- ------------
1           2010        2
2           2010        1
2           2011        2
3           2012        1
4           2013        1
5           2014        3
5           2015        4
5           2016        5