【问题标题】:Cummulative SUM based on columns基于列的累积 SUM
【发布时间】:2017-09-07 11:11:02
【问题描述】:

我有一张表,其值如下:

我想根据IDyear 获得累积总和,因此它应该返回这样的输出,即对于 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。因此要做什么。有人可以帮忙吗?

标签: sql sql-server sql-server-2016


【解决方案1】:

没有必要让想法变得比他们需要的更复杂......

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

【讨论】:

    【解决方案2】:

    这比我想要的嵌套更多,我觉得有一种更好的方法可以做到这一点,也许只有一个 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 函数以按年份计算行数的运行总计。

    【讨论】:

      【解决方案3】:

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

      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(编辑:请参阅下面的答案以了解这种技术,我认为对于这样一个简单的任务来说它有点太复杂了)。上面的查询返回你需要的输出

      +--------+------+-------+
      | 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 |
      +--------+------+-------+
      

      【讨论】:

      • 你能帮我看看如何用 row_number 做到这一点
      • 您可以使用下面 ttallierchio 的选择查询。只需将your_table 替换为#table_name 并将id 替换为UserID
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-29
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 2021-07-20
      相关资源
      最近更新 更多