在SQL中使用前一行中的上一个值作为null

时间:2018-11-16 16:53:20

标签: mysql sql

我试图用先前的值填充所有空值,但前提是字段帐户相同。我了解到我的表需要有一个主键。目前,我的表上没有它,可以使用表的行数创建一个,请参见下表:

CREATE TABLE test (ACCOUNT_NO INT, RATE INT, DATE_L DATE, ROWCOUNT INT);    
   INSERT INTO test VALUES (1, 3, '2017-12-31',1);
   INSERT INTO test VALUES (1, NULL, '2018-01-31',2);
   INSERT INTO test VALUES (3, 5, '2017-12-31',3);
   INSERT INTO test VALUES (3, NULL, '2018-01-31',4);
   INSERT INTO test VALUES (3, NULL, '2018-02-28',5);
   INSERT INTO test VALUES (6, 2, '2018-03-04',6);
   INSERT INTO test VALUES (6, NULL, '2018-03-04',7);
   INSERT INTO test VALUES (6, 5, '2018-03-04',8);
   INSERT INTO test VALUES (6, NULL, '2018-03-04',9);
   INSERT INTO test VALUES (6, NULL, '2018-03-04',10);

所以表看起来像这样:

|ACCOUNT_NO|RATE|DATE_L    |RowCount|
|1         |3   |2017-12-31|1       |
|1         |NULL|2018-01-31|2       |
|3         |5   |2017-12-31|3       |
|3         |NULL|2018-01-31|4       |
|3         |NULL|2018-02-28|5       |
|6         |2   |2018-03-04|6       |
|6         |NULL|2018-03-04|7       |
|6         |5   |2018-03-04|8       |
|6         |NULL|2018-03-04|9       |
|6         |NULL|2018-03-04|10      |

我希望它看起来像这样:

|ACCOUNT_NO|RATE|DATE_L    |RowCount|
|1         |3   |2017-12-31|1       |
|1         |3   |2018-01-31|2       |
|3         |5   |2017-12-31|3       |
|3         |5   |2018-01-31|4       |
|3         |5   |2018-02-28|5       |
|6         |2   |2018-03-04|6       |
|6         |2   |2018-03-04|7       |
|6         |5   |2018-03-04|8       |
|6         |5   |2018-03-04|9       |
|6         |5   |2018-03-04|10      |

欢迎您的帮助,并先谢谢您。

3 个答案:

答案 0 :(得分:0)

您的问题似乎不是基于上一个值,而是基于同一NULL的非account_no值。

update test t join
       (select account_no, max(rate) as max_rate
        from test t
        group by account_no
       ) a
       using (account_no)
    set t.rate = a.max_rate
    where t.rate is null;

答案 1 :(得分:0)

稍后将对其进行编辑,ROWCOUNT列用于定义“上一行/最后一行”。基本前提是,较低的ROWCOUNT值表示“较旧/先前”行。

然后您可以将Correlated Subquery与条件CASE .. WHEN表达式一起使用,以确定同一NON NULL的最后一个ACCOUNT_NO值:

查询

SELECT
  t1.ACCOUNT_NO, 
  CASE WHEN t1.RATE IS NULL 
         THEN (SELECT t2.RATE 
               FROM test AS t2 
               WHERE t2.ROWCOUNT < t1.ROWCOUNT AND 
                     t2.ACCOUNT_NO = t1.ACCOUNT_NO AND 
                     t2.RATE IS NOT NULL 
               ORDER BY t2.ROWCOUNT DESC 
               LIMIT 1)
       ELSE t1.RATE
  END AS RATE, 
  t1.DATE_L, 
  t1.ROWCOUNT 
FROM test AS t1;

结果

| ACCOUNT_NO | DATE_L     | ROWCOUNT | RATE |
| ---------- | ---------- | -------- | ---- |
| 1          | 2017-12-31 | 1        | 3    |
| 1          | 2018-01-31 | 2        | 3    |
| 3          | 2017-12-31 | 3        | 5    |
| 3          | 2018-01-31 | 4        | 5    |
| 3          | 2018-02-28 | 5        | 5    |
| 6          | 2018-03-04 | 6        | 2    |
| 6          | 2018-03-04 | 7        | 2    |
| 6          | 2018-03-04 | 8        | 5    |
| 6          | 2018-03-04 | 9        | 5    |
| 6          | 2018-03-04 | 10       | 5    |

View on DB Fiddle

答案 2 :(得分:0)

在下面的简单查询中使用。您可以得到预期的结果。

UPDATE test AS t1
INNER JOIN 
    (SELECT ACCOUNT_NO, RATE FROM test WHERE RATE !='' GROUP BY ACCOUNT_NO) AS t2 ON t1.ACCOUNT_NO=t2.ACCOUNT_NO
SET t1.RATE=t2.RATE
WHERE t1.RATE IS NULL OR t1.RATE = ''