簡體   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