繁体   English   中英

获取多个分区中的下一个(或上一个)非空值

[英]Get the next (or previous) non-null value in multiple partitioned

下面的示例数据。

我想根据行(实际上是时间戳)基于相同 id 的下一个非空值清理数据。

  • 我不能做滞后,因为在某些情况下会有连续的空值。
  • 我不能做 coalesce(a.col_a, (select min(b.col_a) from table b where a.id=b.id)) 因为它会返回一个“过时”的值(例如,在 col_a 行中是 NYC 而不是 SF 4)。 (我可以这样做,一旦我考虑了其他所有内容,对于我没有下一个非空值的情况,比如 col_b 第 9/10 行,只填写最后一个)。

我唯一能想到的就是做

table_x as (select id, col_x from table where col_a is not null)

对于每一列,然后以 id = id 和 table_x.row > table.row 的最小值连接。 但是我有一些专栏,感觉很麻烦而且效率低下。

感谢任何帮助!

ID 可乐 col_a_desired col_b col_b_desired
0 1 - 纽约市 红色的 红色的
1 1 纽约市 纽约市 红色的 红色的
2 1 顺丰 顺丰 - 蓝色的
3 1 - 顺丰 - 蓝色的
4 1 顺丰 顺丰 蓝色的 蓝色的
5 2 标准杆 标准杆 红色的 红色的
6 2 伦敦 伦敦 - 蓝色的
7 2 伦敦 伦敦 - 蓝色的
8 2 - 伦敦 蓝色的 蓝色的
9 2 伦敦 伦敦 - 蓝色的
10 2 - 伦敦 - 蓝色的

我想根据下一个非空值清理数据。

所以如果你颠倒顺序,那是最后一个非空值。

如果你有多个列,并且逻辑太繁琐而无法在 SQL 中编写,则可以改为使用 plpgsql 编写,甚至使用您选择的脚本语言(但这会更慢)。

这个想法是打开一个 cursor 进行更新,其中 ORDER BY 的顺序与问题中提到的相反。 然后 plpgsql 代码将最后的非空值存储在变量中,如果需要,发出 UPDATE WHERE CURRENT OF cursor 以将表中的空值替换为所需的值。

这可能需要一段时间,而且大量的更新会占用大量的锁。 看起来您的数据可以使用“id”列作为块标识符在独立的块中进行处理,因此使用它是一个好主意。

你可以试试这个查询吗?

WITH samp AS (
  SELECT 0 row_id, 1 id, null col_a, 'red' col_b UNION ALL
  SELECT 1, 1, 'NYC', 'red' UNION ALL
  SELECT 2, 1, 'SF', NULL UNION ALL
  SELECT 3, 1, NULL, NULL UNION ALL
  SELECT 4, 1, 'SF', 'blue' UNION ALL
  SELECT 5, 2, 'PAR', 'red' UNION ALL
  SELECT 6, 2, 'LON', NULL UNION ALL
  SELECT 7, 2, 'LON', NULL UNION ALL
  SELECT 8, 2, NULL, 'blue' UNION ALL
  SELECT 9, 2, 'LON', NULL UNION ALL
  SELECT 10, 2, NULL, NULL
)
  SELECT
  row_id,
  id,
  IFNULL(FIRST_VALUE(col_a IGNORE NULLS) 
    OVER (PARTITION BY id ORDER BY row_id
    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
  FIRST_VALUE(col_a IGNORE NULLS) 
    OVER (PARTITION BY id ORDER BY row_id desc
    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)) AS col_a,
  IFNULL(FIRST_VALUE(col_b IGNORE NULLS) 
    OVER (PARTITION BY id ORDER BY row_id
    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
  FIRST_VALUE(col_b IGNORE NULLS) 
    OVER (PARTITION BY id ORDER BY row_id desc
    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)) AS col_b
 from samp order by id, row_id

Output: 在此处输入图像描述

参考: https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#first_value https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM