SQL Server:按日期更改计算总计数的类型

时间:2015-05-14 16:39:39

标签: sql sql-server-2008 count running-total

我需要在每次更改日期(M_Id)时计算一个值(RS_Date),并创建一个按RS_Date分组的列,该列具有该日期的有效总计。

所以表格是:

Ep_Id   Oa_Id   M_Id M_StartDate    RS_Date
--------------------------------------------
    1   2001    5   1/1/2014       1/1/2014
    1   2001    9   1/1/2014       1/1/2014
    1   2001    3   1/1/2014       1/1/2014
    1   2001    11  1/1/2014       1/1/2014
    1   2001    2   1/1/2014       1/1/2014
    1   2067    7   1/1/2014       1/5/2014
    1   2067    1   1/1/2014       1/5/2014
    1   3099    12  1/1/2014       3/2/2014
    1   3099    14  2/14/2014      3/2/2014
    1   3099    4   2/14/2014      3/2/2014

所以我的目标就像是

RS_Date   Active
-----------------
1/1/2014    5
1/5/2014    7
3/2/2014    10

如果M_startDate = RS_Date我需要计算M_id,然后计算。{ 每个RS_Date不等于开始日期我需要计算M_Id,然后将其添加到M_StartDate计数,然后计算下一个RS_Date并将其添加到最后一次活动计数。

我可以通过类似

的方式获得基本计数
(Case when M_StartDate <= RS_Date
        then [m_Id] end) as Test.

但我被困在如何得到我想要的结果。

非常感谢任何帮助。

布赖恩

- 回复评论 我正在使用Server Ver 10

4 个答案:

答案 0 :(得分:1)

如果使用SQL SERVER 2012+,您可以将ROWS与分析/窗口函数一起使用:

;with cte AS (SELECT RS_Date
                    ,COUNT(DISTINCT M_ID) AS CT
              FROM Table1
              GROUP BY RS_Date
              )
SELECT *,SUM(CT) OVER(ORDER BY RS_Date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Run_CT
FROM cte

演示:SQL Fiddle

如果在2012年之前使用了某些东西,你可以使用:

;with cte AS (SELECT RS_Date
                    ,COUNT(DISTINCT M_ID) AS CT
              FROM Table1
              GROUP BY RS_Date
              )
SELECT a.RS_Date
      ,SUM(b.CT)
FROM cte a
LEFT JOIN cte b
  ON a.RS_DAte >= b.RS_Date
GROUP BY a.RS_Date  

演示:SQL Fiddle

答案 1 :(得分:0)

您需要使用窗口化聚合函数在SQL Server 2012中轻松获得累积总和。根据您的描述,这将返回预期的结果

SELECT p_id, RS_Date,
   SUM(COUNT(*)) 
   OVER (PARTITION BY p_id 
         ORDER BY RS_Date 
         ROWS UNBOUNDED PRECEDING)
FROM tab
GROUP BY p_id, RS_Date

答案 2 :(得分:0)

看起来你想要这样的东西:

SELECT
  RS_Date,
  SUM(c) OVER (PARTITION BY M_StartDate ORDER BY RS_Date ROWS UNBOUNDED PRECEEDING)
FROM
  (
    SELECT M_StartDate, RS_Date, COUNT(DISTINCT M_Id) AS c
    FROM my_table
    GROUP BY M_StartDate, RS_Date
  ) counts

内联视图计算每个(M_StartDateRS_Date)组中的不同M_Id值的计数(仅在组内强制执行的不同),外部查询使用{{1的分析版本在每个SUM()中添加计数。

请注意,此特定查询不会完全重现您的示例结果。它将产生:

M_StartDate

这是因为您的示例数据中的某些行RS_Date Active ----------------- 1/1/2014 5 1/5/2014 7 3/2/2014 8 3/2/2014 2 3/2/2014的行RS_Date比其他行晚M_StartDate。如果这不是你想要的,那么你需要澄清这个问题,这个问题目前似乎有些不一致。

不幸,分析函数在SQL Server 2012之前不可用。在SQL Server 2010中,作业更加混乱。可以这样做:

WITH gc AS (
  SELECT M_StartDate, RS_Date, COUNT(DISTINCT M_Id) AS c
  FROM my_table
  GROUP BY M_StartDate, RS_Date
)
SELECT
  RS_Date,
  (
    SELECT SUM(c)
    FROM gc2
    WHERE gc2.M_StartDate = gc.M_StartDate AND gc2.RS_Date <= gc.RS_Date
  ) AS Active
FROM gc

答案 3 :(得分:-1)

如果您使用的是SQL 2012或更高版本,则可以使用LAG生成总计。

https://msdn.microsoft.com/en-us/library/hh231256(v=sql.110).aspx