基于列的累积 SUM
Cummulative SUM based on columns
我有一个 table 值如下:
我想根据 ID
和 year
获得累计总和,所以它应该 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
我有一个 table 值如下:
我想根据 ID
和 year
获得累计总和,所以它应该 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