首页 > 解决方案 > SQL:为每个组填写缺失的日期

问题描述

我想在我的数据库中填写缺失的日期,但我有不同的组。新单元格应填充每个材料编号的最新日期值这是我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)

亲切的问候,

标签: sqlsql-serverdategroup-bycalendar

解决方案


使用 aCROSS 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)会有所帮助。但是还有一些更复杂的替代方法。如果性能是一个问题,我建议您问另一个问题。


推荐阅读