我正在努力解决以下问题。考虑下面发布的示例表。我需要做的是更新表,特别是每行上的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
答案 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。