SQL使用最后一个值填充间隙,直到新值

时间:2015-12-14 16:55:19

标签: sql sql-server common-table-expression

我在状态列中有一个带有间隙的数据集。类似的问题在这里有缺少的日期,但我的日期是给出的。在这个例子中,我需要最新状态来填补下面的NULL空白,直到出现新状态,然后新状态需要填补空白。

  

例如:
  创建表#tableA

     


  Campaign Varchar(100)
  ,Date_of_data日期
  ,状态varchar(100)
  )

     

插入#tableA
  值
  (' banner1'&#39 11 /2015分之2'' DELIVERING&#39),
  (' banner1'&#39 11 /2015分之3'' DELIVERING&#39),
  (' banner1'&#39 11 /2015分之4',空),
  (' banner1'&#39 11 /2015分之5',空),
  (' banner1'&#39 11 /2015分之6',空),
  (' banner1'&#39 11 /2015分之7',空),
  (' banner1'&#39 11 /2015分之8',空),
  (' banner1'&#39 11 /2015分之9'' PAUSED&#39),
  (' banner1'&#39 11 /二千零十五​​分之十'' PAUSED&#39),
  (' banner1'&#39 11 /二千零十五​​分之十一'' PAUSED&#39),
  (' banner1'&#39 11 /二千零十五​​分之十二',空),
  (' banner1'&#39 11 /二千零一十五分之十三',空),
  (' banner1'&#39 11 /二千零十五​​分之十四',空),
  (' banner1'&#39 11 /二千零十五​​分之十五',空),
  (' banner1'&#39 11 /二千零十五​​分之十六'' DELIVERING&#39),
  (' banner1'&#39 11 /二千零十五​​分之十七'' DELIVERING&#39),
  (' banner1'&#39 11 /二千零十五​​分之十八'' DELIVERING')

     

从#tableA中选择*

状态'提供'在11/3需要填写11 / 4-11 / 8,然后填写' PAUSED' 11/11事件需要填写11 / 12-11 / 15,以便最终的数据集实际上看起来像

  

运动| Date_of_data |状态
  banner1 2015-11-02送货
  banner1 2015-11-03送货
  banner1 2015-11-04送货
  banner1 2015-11-05送货
  banner1 2015-11-06交付
  banner1 2015-11-07送货
  banner1 2015-11-08送货
  banner1 2015-11-09 PAUSED
  banner1 2015-11-10 PAUSED
  banner1 2015-11-11 PAUSED
  banner1 2015-11-12 PAUSED
  banner1 2015-11-13 PAUSED
  banner1 2015-11-14 PAUSED
  banner1 2015-11-15 PAUSED
  banner1 2015-11-16送货
  banner1 2015-11-17送货
  banner1 2015-11-18交付

谢谢!

第二种情况......

以下解决方案有效,但我遇到了新的情况。以下内容适用于" banner1"但是当你到达" banner2" 11 / 12-11 / 15的记录不会充满“准备好”。他们填写了“PAUSED'我不知道为什么。这是一个订购问题吗?

所需逻辑:使用第一个"之前的#34;填充NULL记录状态

  

drop table #tableA
  创建表#tableA
  (
    Campaign Varchar(100),
     Date_of_data日期,
     状态varchar(100)
  )

     

插入#tableA
  值
     (' banner1'&#39 11 /2015分之2'' DELIVERING&#39),
     (' banner1'&#39 11 /2015分之3'' DELIVERING&#39),
     (' banner1'&#39 11 /2015分之4',空),
     (' banner1'&#39 11 /2015分之5',空),
     (' banner1'&#39 11 /2015分之6',空),
     (' banner1'&#39 11 /2015分之7',空),
     (' banner1'&#39 11 /2015分之8',空),
     (' banner1'&#39 11 /2015分之9'' PAUSED&#39),
     (' banner1'&#39 11 /二千零十五​​分之十'' PAUSED&#39),
     (' banner1'&#39 11 /二千零十五​​分之十一'' PAUSED&#39),
     (' banner1'&#39 11 /二千零十五​​分之十二',空),
     (' banner1'&#39 11 /二千零一十五分之十三',空),
     (' banner1'&#39 11 /二千零十五​​分之十四',空),
     (' banner1'&#39 11 /二千零十五​​分之十五',空),
     (' banner1'&#39 11 /二千零十五​​分之十六'' DELIVERING&#39),
     (' banner1'&#39 11 /二千零十五​​分之十七'' DELIVERING&#39),
     (' banner1'&#39 11 /二千零十五​​分之十八'' DELIVERING&#39),
    (' banner2'&#39 11 /2015分之2'' DELIVERING&#39),
     (' banner2'&#39 11 /2015分之3'' DELIVERING&#39),
     (' banner2'&#39 11 /2015分之4',空),
     (' banner2'&#39 11 /2015分之5',空),
     (' banner2'&#39 11 /2015分之6',空),
     (' banner2'&#39 11 /2015分之7',空),
     (' banner2'&#39 11 /2015分之8',空),
     (' banner2'&#39 11 /2015分之9'' READY&#39),
     (' banner2'&#39 11 /二千零十五​​分之十'' READY&#39),
     (' banner2'&#39 11 /二千零十五​​分之十一'' READY&#39),
     (' banner2'&#39 11 /二千零十五​​分之十二',空),
     (' banner2'&#39 11 /二千零一十五分之十三',空),
     (' banner2'&#39 11 /二千零十五​​分之十四',空),
     (' banner2'&#39 11 /二千零十五​​分之十五',空),
     (' banner2'&#39 11 /二千零十五​​分之十六'' DELIVERING&#39),
     (' banner2'&#39 11 /二千零十五​​分之十七'' DELIVERING&#39),
     (' banner2'&#39 11 /二千零十五​​分之十八'' DELIVERING')

     

SELECT Campaign,Date_of_data,
        COALESCE(Status,prevStatus)AS状态

  来自#TableA AS t1
  外部申请(
    SELECT TOP 1状态
    来自#TableA AS t2
    在哪里t1.Date_of_data> t2.Date_of_data AND St​​atus IS NOT NULL
    ORDER BY Date_of_data DESC)AS t3(prevStatus)
  按顺序排列1,2

2 个答案:

答案 0 :(得分:2)

如果您使用的是SQL Server,那么您可以使用OUTER APPLY获得所需的结果:

SELECT Campaign, Date_of_data, 
       COALESCE(Status, prevStatus) AS Status      
FROM #TableA AS t1
OUTER APPLY (
   SELECT TOP 1 Status
   FROM #TableA AS t2
   WHERE t1.Date_of_data > t2.Date_of_data AND Status IS NOT NULL
   ORDER BY Date_of_data DESC) AS t3(prevStatus)
ORDER BY Date_of_data

Demo here

答案 1 :(得分:0)

您可以使用2个窗口函数执行此操作。

您选择的查询使用窗口SUM函数。当存在值时,IIF()函数将返回1,否则将为零。窗口总和将显示Date_of_data增加时的运行总计。这实际上将为值创建一个分组,并且它跟随空值。

用于返回数据的查询将使用该分组并显示存在的第一个值,根据定义,它将是最后一个非空值。

SELECT
  Campaign,
  Date_of_data,
  Status,
  FIRST_VALUE(Status) OVER (
    PARTITION BY Grp
    ORDER BY Date_of_data ASC 
  )
FROM
  (
    SELECT 
      Campaign,
      Date_of_data,
      Status,
      SUM(IIF(Status IS NULL, 0,1)) OVER (ORDER BY Date_of_data ASC) AS 'Grp'
    FROM 
      #tableA
  ) A