我有一份报告,显示从项目开始到当前月份的一系列项目的月度数据。当项目几个月没有数据时,它就不会显示出来。
我需要为每个项目显示缺少的月份行,并为这些行显示0。
可以有2个或更多项目(如100个项目)生成报告。项目开始时间也可以是2014年的早期项目。 假设当前月份是2016年4月。然后报告需要显示从201401到201604的数据。在下面的示例中,我使用项目开始月份作为201512。
所有月份列表都存储在包含所有月份的月份表中。项目开始月份(201512和当前月份201604作为参数传递给storedprocedure)
目前报告看起来像这样
=====================================
|ProjectNo | Period | Billing | WIP |
======================================
|000123 |201512 | 100 | 75 |
| |201601 | 200 | 100 |
--------------------------------------
|000145 |201512 | 100 | 75 |
| |201601 | 200 | 100 |
| |201602 | 250 | 110 |
| |201604 | 550 | 110 |
======================================
返回的数据集如下所示(让结果集调用为ProjectReportData)
=====================================
|ProjectNo | Period | Billing | WIP |
======================================
|000123 |201512 | 100 | 75 |
|000123 |201601 | 200 | 100 |
|000145 |201512 | 100 | 75 |
|000145 |201601 | 200 | 100 |
|000145 |201602 | 250 | 110 |
|000145 |201604 | 550 | 110 |
======================================
如您所见,项目编号000123缺少201602,201603和201604。 对于项目号000145,缺少201603个月。
预期输出就像这样
=====================================
|ProjectNo | Period | Billing | WIP |
======================================
|000123 |201512 | 100 | 75 |
| |201601 | 200 | 100 |
| |201602 | 0 | 0 |
| |201603 | 0 | 0 |
| |201604 | 250 | 110 |
--------------------------------------
|000145 |201512 | 100 | 75 |
| |201601 | 200 | 100 |
| |201602 | 250 | 110 |
| |201603 | 0 | 0 |
| |201604 | 550 | 110 |
======================================
我尝试使用Months表右键加入ProjectReportData, 这将填补失踪的几个月。
|ProjectNo | Period | Billing | WIP |
======================================
|000123 |201512 | 100 | 75 |
|000123 |201601 | 200 | 100 |
|NULL |201602 | NULL | NULL|
|NULL |201603 | NULL | NULL|
|NULL |201604 | NULL | NULL|
|000145 |201512 | 100 | 75 |
|000145 |201601 | 200 | 100 |
|000145 |201602 | 250 | 110 |
|NULL |201603 | NULL | NULL|
|000145 |201604 | 550 | 110 |
======================================
但我还需要填充ProjectNo而不是NULL。
我怎样才能实现这一目标。请建议。
答案 0 :(得分:0)
在CTE中加入交叉联接:
with Projects as
(
select distinct ProjectNumber
from ProjectReportData
)
, Periods as
(
select p.ProjectNumber, c.Period
from Projects p
cross join CalendarTable c
)
select a.*, b.Billing, b.WIP
from Periods a
left join ProjectReportData b
on a.ProjectNumber = b.ProjectNumber
答案 1 :(得分:0)
如果数据库中有Projects表:
select ProjectNo, Period, IsNull(wip, 0) wip , IsNull(billing, 0) billing
from Projects d1
outer apply (
select m.*,d2.wip, d2.billing
from Months m
left join ProjectReportData d2 on m.Period = d2.Period and d2.ProjectNo=d1.ProjectNo
) mm
order by 1, 2 desc
如果您的数据库中没有Projects表:
select ProjectNo, Period, IsNull(wip, 0) wip , IsNull(billing, 0) billing
from (
select distinct ProjectNo
from ProjectReportData
) d1
outer apply (
select m.*,d2.wip, d2.billing
from Months m
left join ProjectReportData d2 on m.Period = d2.Period and d2.ProjectNo=d1.ProjectNo
) mm
order by 1, 2 desc