更新null列时的技巧

时间:2017-08-28 07:42:08

标签: sql oracle

您好我有以下查询更新前一个值的列 其中column为null:

UPDATE day_status a 
SET a.ch_size = 
( 
  SELECT LAG(ch_size) OVER (ORDER BY item, daytime) as prev_choke
  FROM day_status b
  WHERE a.item = b.item AND a.daytime=b.daytime
) 
WHERE a.ch_size IS NULL AND a.sub_hours = 0.5

但由于某种原因,它在前一个值时设置为null,请参见下面的示例:

Item daytime               sub_hours  ch_size prev_choke
 -------------------------------------------------------
 t23  18-Aug-17 03:30:00    0.5        56.8   
 t23  18-Aug-17 04:00:00    0.5               56.8
 t24  18-Aug-17 02:30:00    0.5        40.8
 t24  18-Aug-17 04:40:00    0.5               40.8  
 t24  18-Aug-17 02:30:00    0          45.4

这就是表格的样子:

 Item daytime               sub_hours  ch_size
  -------------------------------------------------------
  t23  18-Aug-17 03:30:00    0.5        56.8
  t23  18-Aug-17 04:00:00    0.5  
  t24  18-Aug-17 02:30:00    0.5        40.8
  t24  18-Aug-17 04:40:00    0.5           
  t24  18-Aug-17 02:30:00    0          45.4
  t23  19-Aug-17 03:30:00    0.5        70.2
  t23  19-Aug-17 04:00:00    0.5  
  t24  19-Aug-17 02:30:00    0.5        40.8
  t24  19-Aug-17 04:40:00    0.5           
  t24  19-Aug-17 02:30:00    0.2   

这个表在更新后应如何显示:

 Item daytime               sub_hours  ch_size
  -------------------------------------------------------
  t23  18-Aug-17 03:30:00    0.5        56.8
  t23  18-Aug-17 04:00:00    0.5        56.8
  t24  18-Aug-17 02:30:00    0.5        40.8
  t24  18-Aug-17 04:40:00    0.5        40.8  
  t24  18-Aug-17 02:30:00    0          45.4
  t23  19-Aug-17 03:30:00    0.5        70.2
  t23  19-Aug-17 04:00:00    0.5        70.2
  t24  19-Aug-17 02:30:00    0.5        40.8
  t24  19-Aug-17 04:40:00    0.5        40.8       
  t24  19-Aug-17 02:30:00    0.2   

哪里可能是一招?

1 个答案:

答案 0 :(得分:3)

lag()where子句后计算。所以,你可以这样做:

UPDATE day_status ds
    SET ch_size = (SELECT prev_choke
                   FROM (SELECT d2.*,
                                LAG(ch_size) OVER (ORDER BY item, daytime) as prev_choke
                         FROM day_status ds2
                        ) ds2
                   WHERE ds.item = ds2.item AND ds.daytime = ds2.daytime
                  ) 
WHERE a.ch_size IS NULL AND a.sub_hours = 0.5;

我还假设您打算partition by item order by daytime

编辑:

严格来说,您可以添加:

UPDATE day_status ds
    SET ch_size = (SELECT prev_choke
                   FROM (SELECT d2.*,
                                LAG(ch_size) OVER (ORDER BY item, daytime) as prev_choke
                         FROM day_status ds2
                        ) ds2
                   WHERE ds.item = ds2.item AND ds.daytime = ds2.daytime
                  ) 
WHERE a.ch_size IS NULL AND a.sub_hours = 0.5 AND
      EXISTS (SELECT prev_choke
              FROM (SELECT d2.*,
                           LAG(ch_size) OVER (ORDER BY item, daytime) as prev_choke
                    FROM day_status ds2
                   ) ds2
              WHERE ds.item = ds2.item AND ds.daytime = ds2.daytime AND
                    prev_choke IS NOT NULL
             ) ;

但是,您可能希望采用其他方法,例如使用merge