SQL:为每个组填写缺少的日期

时间:2019-10-02 09:48:41

标签: sql sql-server date group-by calendar

我想在数据库中填写缺少的日期,但是我有不同的组。新单元格应填写每个物料编号的最新日期值 这就是我的database的样子:

Date [YYYY-MM-DD]   Materialnumber            Amount
2019-01-01            X                        5
2019-01-15            X                        7
2019-01-20            X                        2
2019-02-02            X                        8
2019-01-03            Y                        756
2019-01-18            Y                        750
2019-02-22            Y                        720
2019-03-05            Y                        820

我希望它看起来像这样:

Date [YYYY-MM-DD]   Materialnumber            Amount
2019-01-01            X                        5
2019-01-02            X                        5
2019-01-03            X                        5
2019-01-04            X                        5
                     ...
2019-01-15            X                        7
2019-01-16            X                        7
2019-01-17            X                        7
                     ...
2019-01-01            Y                        756
2019-01-02            Y                        756
2019-01-03            Y                        756
                     ...
2019-01-18            Y                        750
2019-01-19            Y                        750
                     ...

我通过执行以下操作创建了一个calendar表:

WITH CTE_DatesTable
AS
(
  SELECT CAST('20190101' as date) AS [Date]
  UNION ALL
  SELECT DATEADD(dd, 1, [date])
  FROM CTE_DatesTable
  WHERE DATEADD(dd, 1, [date]) <= '20191231'
)
SELECT [date] 
KSH_calendar 
FROM CTE_DatesTable
OPTION (MAXRECURSION 0);

我已经尝试过了:

   select c.[Date]
    ,b.Materialnumber
    ,b.Amount
    from KSH_calendar as c
    left join database as b on c.[Date] = b.[MKPF_CPUDT] 

但是,这并不能使我达到预期的结果。甚至没有谈论获得最新价值。 有人有一些想法/链接让我更接近结果吗?

使用Microsoft SQL Server 2017(版本ID 14)

亲切的问候,

1 个答案:

答案 0 :(得分:0)

使用CROSS JOIN生成行,然后输入值。在这种情况下,OUTER APPLY可能是最简单的解决方案:

select c.[Date], m.Materialnumber, d.Amount
from KSH_calendar c cross join
     (select distinct d.Materialnumber
      from database d
     ) m outer apply
     (select top (1) d.*
      from database d
      where d.Materialnumber = m.Materialnumber and
            c.date <= d.MKPF_CPUDT
      order by d.date desc
     ) d;

如果您有很多约会,那么database(materialnumber, MKPF_CPUDT)上的索引会有所帮助。但是有些替代方法要复杂一些。如果性能是一个问题,我建议您再问一个问题。