【问题标题】:Calculating missing months计算缺失的月份
【发布时间】:2019-05-21 10:06:54
【问题描述】:

我使用以下查询来填补缺失的月份

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

我怎样才能添加“产品”?

【问题讨论】:

标签: sql sql-server tsql sql-server-2008


【解决方案1】:

首先,我建议创建一个日历表,因为它每隔一段时间就会作为一个用例弹出。一个简单的例子可以找到here

现在,一旦您准备好日历表(我们称之为 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

【讨论】:

    【解决方案2】:

    使用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 是一个 dbfiddle。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 2013-06-24
      • 2022-09-27
      相关资源
      最近更新 更多