Pyspark - 在右侧数据集中加入空值

Pyspark - Join with null values in right dataset

假设我有一个包含以下内容的数据集:

# dataset_left
 #+-----------------+--------------+---------------+
 #|         A       |       B      |      C        |
 #+-----------------+--------------+---------------+
 #|   some_value_1  | some_value_3 | some_value_5  |
 #+-----------------+--------------+---------------+
 #|   some_value_2  | some_value_4 | some_value_6  |
 #+-----------------+--------------+---------------+

我还有另一个数据集如下:

# dataset_rules
 #+-----------------+--------------+---------------+
 #|         A       |       B      |  result_col   |
 #+-----------------+--------------+---------------+
 #|        null     | some_value_3 |    result_1   |
 #+-----------------+--------------+---------------+
 #|   some_value_2  |      null    |    result_2   |
 #+-----------------+--------------+---------------+

我的目标是使用此规则连接两个数据集:

对于 dataset_rules:列 A 和列 B 中的空值可以匹配 dataset_left 中的任何值。 连接应该只考虑来自 dataset_rules.

的非空值

因此对于 dataset_rule 中的第 1 行,仅应使用第 B 列作为条件。对于第二行,只有 A 列应该用作条件。

我想达到以下预期结果:

# dataset_result
 #+-----------------+--------------+---------------+------------+
 #|         A       |       B      |      C        | result_col |
 #+-----------------+--------------+---------------+------------+
 #|   some_value_1  | some_value_3 | some_value_5  |   result_1 |
 #+-----------------+--------------+---------------+------------+
 #|   some_value_2  | some_value_4 | some_value_6  |   result_2 |
 #+-----------------+--------------+---------------+------------+

目标是避免对 dataset_rules 中的规则进行硬编码,以便于添加新规则并更易于维护。

您可以像这样使用 whencoalesce 表达式加入:

from pyspark.sql import functions as F

join_cond = (
        (F.coalesce(dataset_rules["A"], dataset_left["A"]) == dataset_left["A"])
        & (F.coalesce(dataset_rules["B"], dataset_left["B"]) == dataset_left["B"])
)

result = dataset_left.join(dataset_rules, join_cond, "left").select(
    dataset_left["*"],
    dataset_rules["result_col"]
)

result.show()
#+------------+------------+------------+----------+
#|           A|           B|           C|result_col|
#+------------+------------+------------+----------+
#|some_value_1|some_value_3|some_value_5|  result_1|
#|some_value_2|some_value_4|some_value_6|  result_2|
#+------------+------------+------------+----------+