使用最后一个非空值填充空行值 - SQL表

时间:2013-11-25 21:31:16

标签: sql-server null

我正在努力解决以下问题。考虑下面发布的示例表。我需要做的是更新表,特别是每行上的NULL值和“last”非NULL值。例如,第3行和第4行的NULL值应使用同一列的第2行的值进行更新,即

2   007585102   2001 03 31   2001 04 12   2   154980   6300   154980   6300  
3   007585102   2001 03 31   2001 04 19   2   154980   6300   154980   6300  
4   007585102   2001 03 31   2001 04 26   2   154980   6300   154980   6300
第9行到第15行的

和NULL值使用第8行的值更新,依此类推。 老实说,我不知道该怎么做,我将非常感谢任何帮助。提前谢谢。

很抱歉桌子的格式非常差,但除了纯文本外我不能发布任何内容。

示例表

1    007585102   2001 03 31   2001 04 05   2    543660   22100   543660   22100  
2    007585102   2001 03 31   2001 04 12   2    154980   6300    154980    6300  
3    007585102       NULL     2001 04 19  NULL      NULL    NULL        NULL        NULL  
4    007585102       NULL     2001 04 26  NULL      NULL    NULL        NULL        NULL  
5    007585102   2001 03 31   2001 05 03   2    2726664  110840 2726664 110840  
6    007585102   2001 03 31   2001 05 10   2    836400   34000   836400   34000  
7    007585102   2001 03 31   2001 05 17   2    534804   21740   7634364  310340  
8    007585102   2001 03 31   2001 05 24   2    4920      200      4920       200  
9    007585102       NULL     2001 05 31   NULL     NULL    NULL        NULL    NULL    
10   007585102       NULL     2001 06 07  NULL      NULL    NULL        NULL    NULL  
11   007585102       NULL     2001 06 14  NULL      NULL    NULL        NULL    NULL   
12   007585102       NULL     2001 06 21  NULL      NULL    NULL        NULL    NULL   
13   007585102       NULL     2001 06 28  NULL      NULL    NULL        NULL    NULL   
14   007585102       NULL     2001 07 05  NULL      NULL    NULL        NULL    NULL  
15   007585102       NULL     2001 07 12  NULL      NULL    NULL        NULL    NULL  
16   007585102   2001 06 30   2001 07 19   2    2693301   118300   2693301   118300  
17   007585102   2001 06 30   2001 07 26   2    232220    10200    NULL    NULL  

3 个答案:

答案 0 :(得分:2)

我对自己的回答并不感到自豪,但至少它有效。自己寻找更优雅的方式。我建议递归cte。

drop table #temp
GO
select 
    *
into #temp
from (
    select 1 as id, '2001 03 31' as dat union all
    select 2, '2001 03 31' union all
    select 3, null union all
    select 4, null union all
    select 5, '2001 03 31' union all
    select 6, '2001 03 31' union all
    select 7, '2001 03 31' union all
    select 8, '2001 03 31' union all
    select 9, null union all
    select 10, null union all
    select 11, null union all
    select 12, null union all
    select 13, null union all
    select 14, null union all
    select 15, null union all
    select 16, '2001 06 30' union all
    select 17, '2001 06 30'
) x

update t
set
    t.dat = t2.dat
from #temp t
join (
    select 
        t1.id, max(t2.id) as maxid
    from #temp t1
    join #temp t2
        on t1.id>t2.id
        and t2.dat is not null 
        and t1.dat is null 
    group by 
        t1.id
) x
    on t.id=x.id
join #temp t2
    on t2.id=x.maxid

select * from #temp

答案 1 :(得分:0)

我在这里详细解释了这个: https://koukia.ca/common-sql-problems-filling-null-values-with-preceding-non-null-values-ad538c9e62a6#.k0dxirgwu 这是您需要的TSQL,

SELECT *
INTO #Temp
FROM ImportedSales;

;With CTE
As
(
   SELECT ProductName
          , Id
          , COUNT(ProductName) OVER(ORDER BY Id ROWS UNBOUNDED PRECEDING) As MyGroup
   FROM #Temp
),
GetProduct
AS
(
    SELECT [ProductName]
           , First_Value(ProductName) OVER(PARTITION BY MyGroup ORDER BY Id ROWS UNBOUNDED PRECEDING) As UpdatedProductName
    FROM CTE
)

UPDATE GetProduct
Set ProductName = UpdatedProductName;

SELECT *
FROM #TemP;

答案 2 :(得分:0)

在redshift中,我认为还有其他sql风格,可以结合使用nvl()和lag函数,并在使用lag()时确保使用ignore nulls选项。

我改编自https://blog.jooq.org/2015/12/17/how-to-fill-sparse-data-with-the-previous-non-empty-value-in-sql/

由于我没有看到列标题,因此我将在示例“ date_field”中调用第二个日期字段。

假设您有一个名为“ row_number”的列,可以在其上正确排序值。

那么使用您上面的数据的示例将是

select nvl(date_field,lag(date_field,1)) ignore nulls over ([partition by whatever] order by rownumber). 

这应该在列上方获取最接近的非空值(按您指定的任何列排序),并替换空值,直到达到非空值为止。

忽略空值是键b / c,否则您将只获取第一个非空值,然后获取下一个空值,这样您就只能替换一行。

HTH。