【问题标题】:T-SQL Running Monthly Totals Including Missing MonthsT-SQL 运行每月总计(包括缺失月份)
【发布时间】:2015-06-01 12:44:58
【问题描述】:

我知道这听起来很简单,但我似乎无法理解它。

我有一个临时表,其中包含例如 Handler、MonthName、MonthNumber 和 MTD,这是该月的总数。然后,我需要用这些数据为每个处理程序创建一个从 4 月到 3 月的运行总计。现在,这是我正在努力解决的问题。并非所有 Handler 都会拥有所有月份的数据。

例如。

Handler              MonthName       MonthNo          MTD
Julian Slaughter     April           1                10000
Julian Slaughter     June            3                12000
Julian Slaughter     July            4                10000
Julian Slaughter     September       6                12000
Bob Monkhouse        April           1                5000
Bob Monkhouse        July            4                5000

所以我希望结果看起来像这样

Julian Slaughter     April           1                10000
Julian Slaughter     May             2                10000
Julian Slaughter     June            3                22000
Julian Slaughter     July            4                32000
Julian Slaughter     August          5                32000
Julian Slaughter     September       6                44000

...等到三月

Bob Monkhouse        April           1                5000
Bob Monkhouse        May             2                5000
Bob Monkhouse        June            3                5000
Bob Monkhouse        July            4                10000

...等到三月

我已尝试将 LEFT JOIN 添加到月份名称\数字表中,并且尝试过

OVER(PARTITION ..... ORDER BY ..... RANGE\ROWS) 

但无法获取缺失的月份。

提前致谢,抱歉格式不好,不知道如何在此处制作表格。

编辑 - 这是我的 LEFT JOIN 尝试

SELECT
Months.MonthNo,
Department,
Executive,
#8.MonthNo,
MTD = SUM([TY MTD Prem]) OVER (PARTITION BY Department, Executive, [Exec Code] ORDER BY #8.MonthNo RANGE UNBOUNDED PRECEDING)
FROM Months
LEFT JOIN #8 ON Months.MonthNo = #8.MonthNo

对于一位行政人员,我只得到 4 行,而不是我需要的 12 行。出于数据保护目的,无法向您显示结果。

【问题讨论】:

  • 你使用的是什么 sql server 版本?
  • 带有月份表的外连接是正确的方法。请考虑使用 dll + dml 为示例数据编辑您的问题,以便人们能够更快地为您提供帮助。另外,包括您当前的 sql 查询。
  • 将您的外部连接尝试发布到月份表。这是正确的方法,所以我们只需要调试你所做的。
  • Tanner,我使用的是 SQL Server 2012。
  • 这里有一些测试数据,伙计们sqlfiddle.com/#!3/80fdc/14

标签: sql sql-server tsql


【解决方案1】:
DECLARE @start_date date, @end_date date
SELECT @start_date='2012-04-01',@end_date='2013-03-31'
;WITH xo AS
(
    SELECT @start_date AS cte_start_date
    UNION ALL
    SELECT DATEADD(MONTH, 1, cte_start_date)
    FROM xo
    WHERE DATEADD(MONTH, 1, cte_start_date) <= @end_date   
), x as (
    select *,row_number() over (order by cte_start_date) monthno
  from xo
  )
,  y as (
  select distinct handler from test
)
SELECT y.handler, datename(mm,x.cte_start_date), x.monthno
,(select sum(mtd) from test a where a.handler=y.handler and a.monthno<=x.monthno) mtd
FROM y
cross join x
order by 1,3

参见 SQLFiddle http://sqlfiddle.com/#!3/7d483/15 上的示例

【讨论】:

  • 有确切需求的好答案。
  • 实际上,我更喜欢至少有一些文字来解释你所做的事情的答案。请记住,答案保留在 SO 上供其他人阅读,因此即使 OP 仅通过查看代码就能理解您的问题,其他人稍后可能会遇到困难。
【解决方案2】:

抱歉耽搁了。提议的解决方案很有效。我不得不在我的巨型查询的其他各个部分多次使用相同的代码,但效果很好。

【讨论】:

    猜你喜欢
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多