如何扫描表的每一行,并根据前一行更新当前行?

时间:2017-08-03 08:35:53

标签: sql sql-server

我需要使用以下逻辑更新当前行:

  1. 如果当前行为空,则将其设置为上一行
  2. 如果当前行不为null,则不执行任何操作
  3. 第1行不为空,然后NULL随机出现

    需要使用前面提到的逻辑更新那些NULL

    e.g。

     1. 1
     2. null
     3. null
     4. 2
     5. null
     6. null
    

    需要更新为

     1. 1
     2. 1
     3. 1
     4. 2
     5. 2
     6. 2
    

    如何在SQL中执行此操作?

    由于 [R

5 个答案:

答案 0 :(得分:0)

如果一行中有两个Null值,则需要定义表的最小非空值,因此我认为Outer Apply将处理您的问题:

CREATE TABLE #TB(ID Int Identity(1, 1), Value Int)
INSERT INTO #TB([Value]) VALUES(1),(Null),(Null),(2),(Null),(Null)

UPDATE G SET G.Value = GG.Value
FROM 
    #TB AS G
        OUTER APPLY
    (SELECT
        TOP 1 *
    FROM
        #TB AS GG
    WHERE
        GG.Value IS NOT NULL
        AND
        GG.ID < G.ID
    ORDER BY
        GG.ID DESC
    ) AS GG
WHERE
    G.Value IS NULL

SELECT * FROM #TB AS T

但请注意,如果第一个值为Null,它将不会为您提供结果,因为您尚未定义此方案的逻辑。

答案 1 :(得分:0)

这可能会有所帮助:

    SELECT
      t1.col1,
      t1.col2 AS previous,
      (SELECT
        t2.col2
      FROM table_1 t2
      WHERE t2.col1 = (SELECT
        MAX(t3.col1)
      FROM table_1 t3
      WHERE t3.col1 <= t1.col1
      AND col2 IS NOT NULL))
      AS new
    FROM table_1 t1;

结果

output

答案 2 :(得分:0)

您在哪里使用此SQL代码?例如,如果您使用的是Hive SQL,则有一个函数可以直接获取最后一个非空值:

LAST_VALUE(col, true) over (PARTITION BY id ORDER BY date)

Oracle 10g还有一个执行此操作的功能,正如此主题中所述:

Fill null values with last non-null amount - Oracle SQL

您熟悉窗口功能吗?

答案 3 :(得分:0)

while (select count(*) FROM Table_1 where c1_derived = '') > 0
begin
    update top(1) Table_1
    set c1_derived = (select c1_derived from Table_1 t2 where (t2.id = [Table_1].id-1))
    where c1_derived = ''
end

答案 4 :(得分:0)

尝试以下脚本。 (sql 2008 +)

CREATE TABLE #table(id Int Identity(1, 1), value Int)
INSERT INTO #table([Value]) VALUES(1),(Null),(Null),(2),(Null),(Null)


;WITH cte AS
 (
    SELECT ID,Value,ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS row
    FROM #table
 ) 
 SELECT a.ID,max(b.Value) 
FROM cte a
    INNER JOIN cte b ON a.row >=b.row
 GROUP BY a.ID

 drop table #table

Edit2这也是另一个使用&#34; UNBOUNDED PRECEDING&#34;

的脚本
CREATE TABLE #table(id Int Identity(1, 1), value Int)
INSERT INTO #table([Value]) VALUES(1),(Null),(Null),(2),(Null),(Null)

select *   ,max(t.value)  over(order by Id Rows UNBOUNDED PRECEDING) maxValue
from #table t


drop table #table

查看此链接&#34; OVER Clause&#34; https://docs.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql