Объединение 2 таблиц в pyspark, несколько условий, левое соединение?

#apache-spark #pyspark #apache-spark-sql #pyspark-dataframes

#apache-spark #apache-spark-sql #pyspark

Вопрос:

У меня есть 2 таблицы, как показано ниже. Мой приведенный ниже код объединяет 2 таблицы (левое соединение). Проблема в том, что я должен выполнить одно и то же соединение дважды. Первое объединение выполняется для log_no и LogNumber, которое возвращает все записи из левой таблицы (table1) и соответствующие записи из правой таблицы (table2). Второе соединение выполняет то же самое, но в подстроке log_no с LogNumber . например, 777 будет совпадать с 777 из таблицы 2, 777-A совпадения нет, но при использовании функции подстроки 777-A становится 777, который будет сопоставлен в таблице 2.

введите описание изображения здесь

Вместо создания 2 отдельных объединений, как показано ниже, как я могу охватить оба сценария одним объединением. Код ниже:

 # first join to match 1234-A (table 1) with 1234-A (table 2)
df5 = df5.join(df_app, trim(df5.LOG_NO) == trim(df_app.LogNumber), "left")
         .select (df5["*"], df_app["ApplicationId"])
df5 = df5.withColumnRenamed("ApplicationId","ApplicationId_1")
        
# second join with substring function, to match 777-C with 777, 
# my string is longer than my examples, this is why I have a substring for the first 8 characters. I provided simple examples.

df5 = df5.join(df_app, substring(trim(df5.LOG_NO), 1, 8) == trim(df_app.LogNumber), "left")
         .select (df5["*"], df_app["ApplicationId"])
df5 = df5.withColumnRenamed("ApplicationId","ApplicationId_2")
  

Ответ №1:

Вы можете объединить два условия соединения, используя побитовое ИЛИ:

 df5 = df5.join(df_app, 
               (trim(df5.LOG_NO) == trim(df_app.LogNumber)) |
               (substring(trim(df5.LOG_NO), 1, 8) == trim(df_app.LogNumber)), 
               "left") 
         .select(df5["*"], df_app["ApplicationId"])
  

Комментарии:

1. Я в замешательстве, почему И? это означает, что оба условия должны быть истинными. Если первое условие не выполняется, то условие подстроки должно быть истинным.

2. @AJR Извините, должно быть ИЛИ. Отредактировал мой ответ.

3. Моя программа не завершается…. Мне пришлось убить его после удвоения времени. Обычно моя работа по склеиванию занимает около 22 минут, я дал ей поработать 44 минуты, и она все еще работала… По какой-то причине я думаю, что побитовое ИЛИ помещает мою программу в цикл, и она не завершается. Любой другой совет?? Спасибо

4. @AJR Сначала попробуйте использовать меньший фрейм данных, чтобы убедиться, что он выполняет работу правильно. Нет никакого способа, чтобы «ИЛИ» поместило вашу программу в цикл. Это просто невозможно.