問題描述
我的意圖是執行以下操作:
new data給定一個包含一個或多個日期的表格:

還有一個目標表,historical data如下所示:

我想替換日期范圍(在這個例子中它只有一天 17/10/2022),historical data以便結果如下圖所示:

暫定的
為了達到這個結果,我的第一個實作是使用MERGE INTO下面的 Databricks SQL 子句:
MERGE INTO historical_data
USING new_data
ON historical_data.Date = new_data.Date
WHEN MATCHED
UPDATE SET *
WHEN NOT MATCHED
THEN INSERT *
但是這段代碼會引發這樣的錯誤:
UnsupportedOperationException: Cannot perform Merge as multiple source rows matched and attempted to modify the
same target row in the Delta table in possibly conflicting ways.
該錯誤是不言自明的,我發現解決該問題的唯一方法是執行兩步 SQL。
我目前的解決方案
首先,洗掉目標表中的范圍,然后插入新內容。
在這里你可以看到實作:
--DELETE THE RANGE FROM THE TARGET TABLE
DELETE FROM historical_data
WHERE
historical_data.Date >= (SELECT MIN(new_data.Date) FROM new_data) AND
historical_data.Date <= (SELECT MAX(new_data.Date) FROM new_data);
-- INSERT THE NEW DATA INTO THE HISTORICAL TABLE
INSERT INTO TABLE historical_data
SELECT * FROM new_data;
缺點和主要問題
此實作的缺點是它不會原子地執行操作,而是分兩步完成。我不期望這種行為,因為萬一腳本由于某種原因中斷,總是有可能有一個包含已洗掉資料的表并丟失新資料。我正在尋找一種方法來解決這個問題。有人知道如何幫助我嗎?
uj5u.com熱心網友回復:
沒有辦法繞過 MERGE 的限制。
如果您的資料量很小,您可以覆寫整個表。
INSERT OVERWRITE historical_data
SELECT Date, DocNum, Value
FROM historical_data
WHERE Date NOT IN (SELECT Date FROM new_data)
UNION ALL
SELECT Date, DocNum, Value
FROM new_data;
或者,如果卷很大,但不同日期的數量并不極端,則按日期對表進行磁區。這允許您在動態磁區覆寫模式下僅覆寫特定磁區,并使您的查詢非常簡單:
INSERT OVERWRITE historical_data
SELECT Date, DocNum, Value
FROM new_data;
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/516657.html
標籤:sql阿帕奇火花apache-spark-sql数据块天蓝色数据块
