总数计算

时间:2017-08-04 17:55:26

标签: sql sql-server sql-server-2008 tsql

我正在使用以下数据和SQL编写存储过程。当我执行下面的SQL时,我每个月都会得到计数,但是当我下个月做的时候,我希望计数加起来。我想在查询中添加一个额外的列(Totalcount),我期待结果如下所示。提前谢谢!

 Month_NUMBER  MonthlyCount  Totalcount
 --------------------------------------
  1              4             4
  2              1             5 
  3              1             6
  4              2             8 

这是我目前正在使用的SQL:

drop table #test 

create table #test (name varchar(10), MON_NUMBER int)

insert into #test 
values ('XYZ', 1), ('ABC', 1), ('AZZ', 1), ('BCC', 1),
       ('HAS', 2), ('MRD', 3), ('GIV', 4), ('GIVE', 4)

SELECT 
    MON_NUMBER, 
    COUNT(NAME) AS MonthlyCount  
FROM 
    #test
GROUP BY 
    MON_NUMBER

5 个答案:

答案 0 :(得分:2)

您可以使用以下查询:

Select *, Sum(MonthlyCount) over(order by Mon_nUmber) from (
    SELECT MON_NUMBER, COUNT(NAME) AS MonthlyCount  
    FROM #test
    group by MON_NUMBER
) a

输出如下:


+------------+--------------+------------+
| MON_NUMBER | MonthlyCount | TotalCount |
+------------+--------------+------------+
|          1 |            4 |          4 |
|          2 |            1 |          5 |
|          3 |            1 |          6 |
|          4 |            2 |          8 |
+------------+--------------+------------+

答案 1 :(得分:1)

[0]这种类型的计算值被命名为running total。

[1] SUM()OVER(ORDER BY ...)仅从SQL2012 +

开始可用

[2]以下解决方案应该适用于旧版本(包括此处的SQL2008)和少量数据:

create table #test (name varchar(10), MON_NUMBER int)

insert into #test 
values ('XYZ', 201701), ('ABC', 201701), ('AZZ', 201701), ('BCC', 201701),
       ('HAS', 201702), ('MRD', 201703), ('GIV', 201704), ('GIVE', 201704)

;WITH BaseQuery
AS (
SELECT 
    MON_NUMBER, 
    COUNT(NAME) AS MonthlyCount  
FROM 
    #test
GROUP BY 
    MON_NUMBER
)
SELECT  *, (
            SELECT SUM(x.MonthlyCount) FROM BaseQuery x 
            WHERE x.MON_NUMBER <= bq.MON_NUMBER
        ) AS MonthlyCountRunningTotal
FROM    BaseQuery bq

答案 2 :(得分:1)

您可以在SQL Server 2008中使用自联接:

WITH CTE AS (
    SELECT MON_NUMBER, COUNT(NAME) AS MonthlyCount  
    FROM #test
    group by MON_NUMBER
)
SELECT C1.MON_NUMBER, C1.MonthlyCount, SUM(C2.MonthlyCount) AS TotalCount
FROM CTE C1
JOIN CTE C2 ON C1.MON_NUMBER >= C2.MON_NUMBER
GROUP BY C1.MON_NUMBER, C1.MonthlyCount
ORDER BY C1.MON_NUMBER, C1.MonthlyCount;

答案 3 :(得分:0)

窗口功能可以在这里工作 - 给它一个旋转。

SELECT DISTINCT
    MON_NUMBER, 
    COUNT(NAME) AS MonthlyCount, 
    COUNT(name) OVER (ORDER BY mon_number)
FROM #test
group by MON_NUMBER, NAME
Order by MON_NUMBER
  

窗口文档:https://docs.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql

答案 4 :(得分:0)

@ S.Yang已经给出了最好和正确的答案。由于SUM()窗口函数不能在SQL Server 2008中使用,因此必须使用自联接。基于他的回答,我提交了另一个解决方案,该解决方案通过不使用CTE对大型数据集很有用。

IF OBJECT_ID(N'dbo.temp', N'U') IS NOT NULL DROP TABLE dbo.temp;
SELECT MON_NUMBER, COUNT(NAME) AS MonthlyCount
INTO dbo.temp
FROM #test
GROUP BY MON_NUMBER;

-- Create Index
CREATE INDEX IX_dbo_temp ON dbo.temp (MON_NUMBER, MonthlyCount);

SELECT t1.MON_NUMBER, t1.MonthlyCount, SUM(t2.MonthlyCount) AS TotalCount
FROM dbo.temp AS t1
INNER JOIN dbo.temp AS t2 ON (t2.MON_NUMBER <= t1.MON_NUMBER)
GROUP BY t1.MON_NUMBER, t1.MonthlyCount;

-- Drop temporary tables
IF OBJECT_ID(N'dbo.temp', N'U') IS NOT NULL DROP TABLE dbo.temp;