Sql server 查看以填补日期空白,但仅当给定日期没有记录时

Sql server 查看以填补日期空白,但仅当给定日期没有记录时,sql-server,sql-server-2012,Sql Server,Sql Server 2012,我有一个基本的2列数据表,其中包含名称(VARCHAR)和日期(DATE),这是日常扫描过程的结果。这些名字通常会在多个日期重复,但它们可能每天都不同。不能重复任何名称/日期组合(复合主键)。我正在使用SQL Server 2012 MyName | MyDate ------ | ---------- ABC | 2017-04-11 DEF | 2017-04-11 GHJ | 2017-04-11 ABC | 2017-04-10 DEF | 2017-04-

我有一个基本的2列数据表,其中包含名称(VARCHAR)和日期(DATE),这是日常扫描过程的结果。这些名字通常会在多个日期重复,但它们可能每天都不同。不能重复任何名称/日期组合(复合主键)。我正在使用SQL Server 2012

MyName | MyDate
------ | ----------
ABC    | 2017-04-11
DEF    | 2017-04-11
GHJ    | 2017-04-11
ABC    | 2017-04-10
DEF    | 2017-04-10
GHJ    | 2017-04-10
ABC    | 2017-04-08
GHJ    | 2017-04-08
我需要创建一个视图,该视图将在两个定义的日期之间从表中提取此信息,如果该范围内的任何给定日期都没有记录,则根据以前可用的日期生成该日期的记录

因此,使用上述示例,对于2017-04-08至2017-04-11的日期范围,2017-04-09没有记录-因此我想复制2017-04-08的记录(记录可用的前一个日期),并将其包含在返回的数据集中,ála:

  MyName | MyDate
-------- | ----------
  ABC    | 2017-04-11
  DEF    | 2017-04-11
  GHJ    | 2017-04-11
  ABC    | 2017-04-10
  DEF    | 2017-04-10
  GHJ    | 2017-04-10
**ABC    | 2017-04-09**
**GHJ    | 2017-04-09**
  ABC    | 2017-04-08
  GHJ    | 2017-04-08
我希望这样做,而不是将“间隙填充”过程作为扫描/导入表的一部分,这样我就可以轻松地回顾性地确定扫描失败的日期(但仍然能够生成一个完整的数据集,记录每个日期,即使间隙只是捏造的)

我已经在网站上搜寻了一个解决方案,但我发现的唯一的解决方案似乎适用于每个日期只有一条记录的表格,并相应地填补了“单一”的空白(通常是零,而不是采用以前的值)


我可以生成定义范围内所有日期的临时表,并使用外部联接从表中添加真实数据,但鉴于每个日期可以有多个记录,我如何填补空白?我只考虑在给定日期没有记录的间隙,

可以使用表值函数,允许使用参数,因此不需要硬编码。p> 返回的表包括一个额外的列
Ins
;原始数据为0,插入数据为1

如果你喜欢一个视图,你可以很容易地提取逻辑

create function myFun(@start date, @end date) 
returns @result table (MyName varchar(10), MyDate date, Ins bit) as
begin
;
    with dates as (
        SELECT  DATEADD(DAY, nbr - 1, @start) dt
        FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
                  FROM      sys.columns c
                ) nbrs
        WHERE   nbr - 1 <= DATEDIFF(DAY, @start, @end)
    ), last_avail as (
        select dates.dt, max(t.MyDate) prev_dt
        from dates join t on dates.dt >= t.MyDate
        group by dates.dt
    ), empty as (
        select * from last_avail where dt <> prev_dt
    )
    insert @result (MyName, MyDate, Ins)
    select MyName, MyDate, 0 from t
    union all
    select t.MyName, x.dt, 1
    from empty x join t on x.prev_dt = t.MyDate;

    return;
end
归属


已找到充当日历表角色的常用表表达式。

请更正我的错误,我认为不可能有参数化视图。因此,您需要使用表值函数;可以将日期范围硬编码到视图中以避开此问题(例如,从今天起的最后6个月,或者在表中可用的最小日期和最大日期之间),谢谢,这太棒了!然而。。。这不是假设记录之间只有一个日期间隔吗?因此,如果存在超过一个连续日期的间隔(例如,4月1日和4月8日的记录,而这两个日期之间没有任何间隔),它将为4月2日执行必要的操作(取4月1日的值),但返回的数据集中仍将缺少4月3日到4月7日(没有直接使用的前一天)?恐怕您是正确的。让我研究一会儿,我想我已经纠正了它;我引入了一个新的CTE
last\u avail
,它为所选时间间隔内的每个日期提供了表中存在数据的最大日期。太棒了!是的,这很有魅力。非常感谢Giorgos!太好了,保重!
declare @start date, @end date;

set @start = '2017-04-08';
set @end = '2017-04-11';
select * from dbo.myFun(@start, @end) order by MyDate desc, MyName asc;