SQL 服务器:按日期变化计算总数的类型
SQL Server : count types with totals by date change
我需要在日期 (RS_Date
) 的每次更改时计算一个值 (M_Id
),并创建一个按 RS_Date
分组的列,该列具有来自该日期的活动总数日期。
所以 table 是:
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.
但我不知道如何获得我想要的结果。
如有任何帮助,我们将不胜感激。
布莱恩
-为回应评论而添加
我正在使用服务器版本 10
如果您使用的是 SQL 2012 或更新版本,您可以使用 LAG 生成 运行 总数。
https://msdn.microsoft.com/en-us/library/hh231256(v=sql.110).aspx
您需要一个累计总和,在 SQL Server 2012 中使用窗口聚合函数很容易。根据您的描述,这将 return 预期结果
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
如果使用 SQL SERVER 2012+,您可以将 ROWS
与 analytic/window 函数一起使用:
;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
看起来你想要这样的东西:
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_StartDate
, RS_Date
) 组中不同 M_Id 值的计数(仅在组内强制执行不同),外部查询使用SUM()
的分析版本将每个 M_StartDate
.
中的计数相加
请注意,此特定查询不会完全重现您的示例结果。它会产生:
RS_Date Active
-----------------
1/1/2014 5
1/5/2014 7
3/2/2014 8
3/2/2014 2
这是因为您的示例数据中某些行 RS_Date
3/2/2014 比其他行 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
我需要在日期 (RS_Date
) 的每次更改时计算一个值 (M_Id
),并创建一个按 RS_Date
分组的列,该列具有来自该日期的活动总数日期。
所以 table 是:
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.
但我不知道如何获得我想要的结果。
如有任何帮助,我们将不胜感激。
布莱恩
-为回应评论而添加 我正在使用服务器版本 10
如果您使用的是 SQL 2012 或更新版本,您可以使用 LAG 生成 运行 总数。
https://msdn.microsoft.com/en-us/library/hh231256(v=sql.110).aspx
您需要一个累计总和,在 SQL Server 2012 中使用窗口聚合函数很容易。根据您的描述,这将 return 预期结果
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
如果使用 SQL SERVER 2012+,您可以将 ROWS
与 analytic/window 函数一起使用:
;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
看起来你想要这样的东西:
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_StartDate
, RS_Date
) 组中不同 M_Id 值的计数(仅在组内强制执行不同),外部查询使用SUM()
的分析版本将每个 M_StartDate
.
请注意,此特定查询不会完全重现您的示例结果。它会产生:
RS_Date Active
-----------------
1/1/2014 5
1/5/2014 7
3/2/2014 8
3/2/2014 2
这是因为您的示例数据中某些行 RS_Date
3/2/2014 比其他行 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