透過連接與集合運算子進行資料轉換

已完成

資料工程工作流程常需要結合多個資料集的資訊。 連接運算 會根據相關欄位匹配行以水平組合表格,而 集合運算 則透過附加、交集或排除列來垂直組合表格。 了解何時使用每種方法,有助於建立高效的轉型流程。

在這個單元中,你會學習如何根據關係連接資料表,並應用集合運算子來結合與相符結構的資料集。

結合資料表與聯結

聯結根據相關資料行合併兩個資料表中的資料列。 連接類型決定結果中出現的列數,以及未匹配的列如何處理。

圖解說明如何使用聯接結合表格。

了解連接類型

每種連接類型在資料轉換中都有特定用途:

顯示不同連接類型的圖示。

聯結類型 Description 用例
INNER 只回傳兩個資料表中相符的列 與有效客戶連結訂單
LEFT 回傳左邊表格的所有列;當沒有匹配時,為右邊表格新增 NULL。 包括所有客戶,即使沒有訂單
RIGHT 回傳右表的所有資料列;在沒有匹配的情況下,為左表的資料列新增 NULL。 包括所有部門,即使沒有員工
FULL 返回兩個資料表中的所有資料列;為不匹配的項目新增 NULL 值。 結合資料集以找出任一端的缺口
SEMI 回傳左表格中與右表格匹配的列 篩選下訂單的顧客
ANTI 回傳左邊表格中與右邊表格無匹配的列 尋找從未下過訂單的顧客
CROSS 傳回所有資料列的笛卡兒乘積 產生所有可能的組合

用 SQL 連接資料表

該JOIN子句根據ON或USING指定的條件來組合表格。 考慮員工與部門的資料表,將員工與其所屬部門配對:

-- Inner join: only employees with matching departments
SELECT e.id, e.name, e.deptno, d.deptname
FROM employee e
INNER JOIN department d ON e.deptno = d.deptno;

內部聯結只會傳回三個資料列—部門編號存在於部門資料表中的員工。 第4、5、6部門的員工沒有出現,因為這些部門不在部門表中。

當您需要包含所有員工,不管部門是否相符,請使用左聯結:

-- Left join: all employees, NULL for missing departments
SELECT e.id, e.name, e.deptno, d.deptname
FROM employee e
LEFT JOIN department d ON e.deptno = d.deptno;

這會傳回所有六名員工。 沒有符合部門的項目在 deptname 資料行中顯示 NULL。

將 DataFrames 與 PySpark 連接

PySpark join() 的方法也提供相同的功能。 參數 how 指定連接類型:

df_employee = spark.table("employee")
df_department = spark.table("department")

# Inner join
df_inner = df_employee.join(
    df_department,
    on=df_employee.deptno == df_department.deptno,
    how="inner"
)
display(df_inner)

對於左外聯結、右外聯結或全外聯結,請變更 how 參數:

# Left join: keep all employees
df_left = df_employee.join(
    df_department,
    on="deptno",
    how="left"
)

# Full outer join: keep all rows from both tables
df_full = df_employee.join(
    df_department,
    on="deptno",
    how="full"
)

當兩個 DataFrame 的 join 欄位名稱相同時,將欄位名稱以字串傳遞。 此方法避免結果中出現重複欄位。

使用半連接與反連接篩選資料

半聯結和反聯結功能強大,可以根據資料在另一個資料表中是否存在來篩選資料。 半聯結會傳回左側資料表中符合條件的資料列,而不包含右側資料表的資料行。

-- Find employees who belong to listed departments
SELECT *
FROM employee
LEFT SEMI JOIN department ON employee.deptno = department.deptno;

反連接則返回相反的結果:沒有匹配的行。

-- Find employees in departments not listed
SELECT *
FROM employee
LEFT ANTI JOIN department ON employee.deptno = department.deptno;

在 PySpark 中,請使用 how="semi" 或 how="anti":

# Employees with matching departments
df_semi = df_employee.join(df_department, on="deptno", how="semi")

# Employees without matching departments
df_anti = df_employee.join(df_department, on="deptno", how="anti")

使用集合運算子合併列

集合運算子是垂直運作的,將相同欄位結構的查詢列合併。 與連接不同,集合運算符不會在條件下匹配——它們會堆疊或比較整個結果集。

說明如何將列與集合運算子結合的圖解。

了解集合運算子

Azure Databricks 支援三個集合運算子:

Operator Description 行為
UNION 結合兩個查詢的列 預設會移除重複項目,使用 ALL 來保留重複項目。
INTERSECT 傳回兩個查詢中都存在的資料列 只會出現相符的列數
EXCEPT 傳回來自第一個查詢,而不在第二個查詢中的資料列 預設移除重複項目

兩個查詢必須有相同數量且資料型別相容的欄位。

使用 UNION 合併資料集

UNION 將一個查詢的列附加到另一個查詢。 預設情況下,它會移除重複的:

-- Combine active and archived customers (no duplicates)
SELECT customer_id, name, email FROM active_customers
UNION
SELECT customer_id, name, email FROM archived_customers;

要保留所有列,包括重複的列,請使用 UNION ALL:

-- Combine all rows, keeping duplicates
SELECT customer_id, name, email FROM active_customers
UNION ALL
SELECT customer_id, name, email FROM archived_customers;

當你確定沒有重複或重複有意義時使用 UNION ALL 。 它的效能比較好,因為可以跳過重複刪除步驟。

在 PySpark 中,用 union() 合併 DataFrame。 請注意,PySpark union() 的行為如同 UNION ALL—它會保留重複項。

df_active = spark.table("active_customers")
df_archived = spark.table("archived_customers")

# Combine both tables (keeps duplicates)
df_combined = df_active.union(df_archived)

# Remove duplicates if needed
df_distinct = df_active.union(df_archived).distinct()

用 INTERSECT 尋找常見的列

INTERSECT 僅回傳同時出現於兩個查詢中的列。 這有助於識別重疊資料:

-- Find customers in both active and archived tables
SELECT customer_id FROM active_customers
INTERSECT
SELECT customer_id FROM archived_customers;

此查詢可識別同時出現在兩個資料表中的客戶,對資料品質檢查或需核對的紀錄非常有用。

排除帶有 EXCEPT 的列

EXCEPT 回傳第一個查詢中不存在的列。 這有助於辨識缺口或獨特紀錄:

-- Find active customers not in the archived table
SELECT customer_id FROM active_customers
EXCEPT
SELECT customer_id FROM archived_customers;

你也可以用 MINUS 作為 EXCEPT 的同義詞:

-- Same result using MINUS syntax
SELECT customer_id FROM active_customers
MINUS
SELECT customer_id FROM archived_customers;

像 UNION 一樣,INTERSECT 和 EXCEPT 預設都會移除重複項。 必要時加入 ALL 以保存重複資料。

小提示

在串接集合運算時,請記住 的 INTERSECT 優先順序高於 UNION 和 EXCEPT。 使用括號來控制評估順序。

在聯結與集合運算子之間選擇

連接與集合運算子的選擇取決於你的轉換目標。 連接是將相關表格的欄位水平組合,而集合運算符則是垂直組合列。

需要時使用連接:

  • 透過新增相關資料表的欄位來豐富記錄
  • 根據關鍵關係配對記錄
  • 根據在另一個資料表中是否存在(半聯結/反聯結)來篩選資料

當你需要時,可以使用 集合運算子 :

  • 從多個具有相同結構的來源附加記錄
  • 尋找跨資料集的共同紀錄
  • 識別單一資料集獨有的紀錄

這兩種方法都構成了有效資料轉換流程的基礎。 在下一單元,你將探討如何將轉換後的資料載入 Unity Catalog 中的目標資料表。