计算缺失月份
Calculating missing months
我使用以下查询来填补缺失的月份
Declare @Sample Table(year int, month int,product as nvarchar(50), qty_ytd int);
Insert @Sample(year, month, qty_ytd) Values
(2017, 01,'book', 20),
(2017, 02, 'pc', 30),
(2018, 01, 'book', 50);
;With Months As
(Select 1 As month
Union All
Select month + 1 From Months Where month < 12)
, YearsAndMonths As
(Select distinct year,m.month from @Sample cross join Months m)
select ym.*, coalesce(s.qty_ytd, s2.qty_ytd) qty_ytd, coalesce(s.qty_ytd, 0) QTY from YearsAndMonths ym
left join @sample s on ym.year = s.year and ym.month = s.month
left join (select qty_ytd, year,
row_number() over (partition by year order by month desc) rn
from @Sample) s2 on ym.year = s2.year and rn = 1
我怎样才能添加 'product ' 呢?
首先,我建议创建一个日历 table,因为它每隔一段时间就会作为一个用例弹出。可以找到一个简单的例子 here
现在,一旦您准备好日历 table(我们称它为 static.calendar),代码就相当简单,如下所示:
with Products
as
(
SELECT distinct product
FROM @Sample
),
TimeRange
as
(
SELECT DISTINCT year,
month
FROM static.calendar
)
ProductTimeRange
as
(
SELECT p.products,
tr.year,
tr.month
FROM Products as p
CROSS JOIN TimeRange as tr
)
SELECT ptr.products,
ptr.year,
ptr.month,
s.qty_ytd
FROM ProductTimeRange as ptr
LEFT JOIN @sample as s
ON ptr.products = s.products
AND ptr.year = s.year
AND ptr.month = s.month
ORDER BY ptr.products,
ptr.year,
ptr.month
使用 cross join
生成您想要的行 -- 所有年份、月份和产品。
然后用left join
带入你要的数据:
With Months As (
Select 1 As month
Union All
Select month + 1
From Months
Where month < 12
)
select y.year, m.month, s.product, coalesce(qty_ytd, 0) as qty_ytd
from (select distinct year from @sample) y cross join
months m cross join
(select distinct product from @sample) p left join
@sample s
on s.year = y.year and s.month = m.month and s.product = p.product;
Here 是一个 db<>fiddle.
我使用以下查询来填补缺失的月份
Declare @Sample Table(year int, month int,product as nvarchar(50), qty_ytd int);
Insert @Sample(year, month, qty_ytd) Values
(2017, 01,'book', 20),
(2017, 02, 'pc', 30),
(2018, 01, 'book', 50);
;With Months As
(Select 1 As month
Union All
Select month + 1 From Months Where month < 12)
, YearsAndMonths As
(Select distinct year,m.month from @Sample cross join Months m)
select ym.*, coalesce(s.qty_ytd, s2.qty_ytd) qty_ytd, coalesce(s.qty_ytd, 0) QTY from YearsAndMonths ym
left join @sample s on ym.year = s.year and ym.month = s.month
left join (select qty_ytd, year,
row_number() over (partition by year order by month desc) rn
from @Sample) s2 on ym.year = s2.year and rn = 1
我怎样才能添加 'product ' 呢?
首先,我建议创建一个日历 table,因为它每隔一段时间就会作为一个用例弹出。可以找到一个简单的例子 here
现在,一旦您准备好日历 table(我们称它为 static.calendar),代码就相当简单,如下所示:
with Products
as
(
SELECT distinct product
FROM @Sample
),
TimeRange
as
(
SELECT DISTINCT year,
month
FROM static.calendar
)
ProductTimeRange
as
(
SELECT p.products,
tr.year,
tr.month
FROM Products as p
CROSS JOIN TimeRange as tr
)
SELECT ptr.products,
ptr.year,
ptr.month,
s.qty_ytd
FROM ProductTimeRange as ptr
LEFT JOIN @sample as s
ON ptr.products = s.products
AND ptr.year = s.year
AND ptr.month = s.month
ORDER BY ptr.products,
ptr.year,
ptr.month
使用 cross join
生成您想要的行 -- 所有年份、月份和产品。
然后用left join
带入你要的数据:
With Months As (
Select 1 As month
Union All
Select month + 1
From Months
Where month < 12
)
select y.year, m.month, s.product, coalesce(qty_ytd, 0) as qty_ytd
from (select distinct year from @sample) y cross join
months m cross join
(select distinct product from @sample) p left join
@sample s
on s.year = y.year and s.month = m.month and s.product = p.product;
Here 是一个 db<>fiddle.