SQL fill null values for a field in multiple rows as previous non null value

吃可爱长大的小学妹 提交于 2019-12-06 14:18:54

Try this recursive PostgreSQL query:

WITH RECURSIVE t(id, name, time, value) AS (
  SELECT id, name, time, value FROM test WHERE id = (
    SELECT MIN(id) FROM test
  )
  UNION
  SELECT test.id, COALESCE(test.name, t.name), test.time, test.value
  FROM test, t WHERE test.id = (
    SELECT id FROM test WHERE id > t.id ORDER BY id LIMIT 1
  )
) SELECT * FROM t ORDER BY id;

Notice though that this will probably issue a SELECT on each row. If you don't want that, you can use a view solution:

CREATE VIEW test_view AS
SELECT id, LAG(id) OVER (ORDER BY id) lag_id, name, time, value FROM test;

WITH RECURSIVE t(id, name, time, value) AS (
  SELECT id, name, time, value FROM test_view WHERE lag_id IS NULL
  UNION ALL
  SELECT test_view.id, COALESCE(test_view.name, t.name),
    test_view.time, test_view.value
  FROM test_view, t WHERE test_view.lag_id = t.id
) SELECT * FROM t ORDER BY id;

This should be much faster. The idea is from this article. SQLFiddle: http://sqlfiddle.com/#!15/63f7b/1/1.

This works for me in Access 2010:

SELECT 
    t1.id,
    (
        SELECT TOP 1 t2.name
        FROM test t2
        WHERE t2.id<=t1.id AND t2.name IS NOT NULL
        ORDER BY t2.id DESC
    ) AS name,
    t1.time,
    t1.value
FROM test t1

It should work in other SQL dialects as well, although they may have a slightly different way of doing TOP 1 (e.g., LIMIT 1 is a common variant).

You can achieve this with COALESCE function and subqueries:

SELECT t.id, 
    COALESCE(t.name, (SELECT s.name FROM table s WHERE s.name IS NOT NULL AND s.id < t.id ORDER BY s.id LIMIT 1)) AS name,
    t.time,
    COALESCE(t.value, (SELECT s.value FROM table s WHERE s.value IS NOT NULL AND s.id < t.id ORDER BY s.id LIMIT 1)) AS value
FROM table t ORDER BY t.id

MS Access based solution

SELECT (SELECT last(name)
          FROM test AS temp
          WHERE test.id >= temp.id AND temp.name IS NOT NULL) AS new_name, *
FROM test;

Try using the lead function. Not sure if that works with postgre, for Oracle it does. I think that can help.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!