Spark SQL QUERY объединяется с тем же именем столбца - PullRequest
0 голосов
/ 31 октября 2019

Я пишу запрос на соединение для 2-х фреймов. Я должен выполнить объединение на столбце, который имеет одинаковое имя в обоих таймфреймах. Как я могу написать это в Query?

var df1 = Seq((1,"har"),(2,"ron"),(3,"fred")).toDF("ID", "NAME")
var df2 = Seq(("har", "HARRY"),("ron", "RONALD")).toDF("NAME", "ACTUALNAME")
df1.createOrReplaceTempView("table1")
df2.createOrReplaceTempView("table2")

Я знаю, что мы можем сделать df3 = df1.join(df2, Seq("NAME")), где NAME - это столбец commmon. В этом сценарии df3 будет иметь только ID, NAME, ACTUALNAME.

Если мы сделаем это из SQL, запрос будет select * from table1 LEFT OUTER JOIN table2 ON table1.NAME = table2.NAME. Для этого выходного фрейма данных будет ID, NAME, NAME, ACTUALNAME столбцов. Как убрать лишний столбец NAME, полученный из df2.

Это тоже не работает spark.sql("select * from table1 LEFT OUTER JOIN table2 ON table1.NAME = table2.NAME").drop(df2("NAME"))

Есть ли более чистый способ сделать это? Переименование столбцов df2 - последний вариант, который я не хочу использовать. У меня есть сценарий, в котором создание SQL-запросов проще, чем датафреймов, поэтому ищу только SPARK SQL Специфичные ответы

Ответы [ 4 ]

2 голосов
/ 31 октября 2019

попробуйте это, вы можете использовать col () для ссылки на столбец

scala> spark.sql("select * from table1 LEFT OUTER JOIN table2 ON table1.NAME = table2.NAME").drop(col("table2.NAME")).show()
+---+----+----------+
| ID|NAME|ACTUALNAME|
+---+----+----------+
|  1| har|     HARRY|
|  2| ron|    RONALD|
|  3|fred|      null|
+---+----+----------+
0 голосов
/ 31 октября 2019

Это в основном академическое упражнение, но вы также можете сделать это без необходимости отбрасывать столбцы, включив возможность Spark SQL для интерпретации регулярных выражений в идентификаторах в кавычках - возможность, унаследованная от Hive SQL. Вам нужно установить spark.sql.parser.quotedRegexColumnNames в true при создании контекста Spark, чтобы это работало.

$ spark-shell --master "local[*]" --conf spark.sql.parser.quotedRegexColumnNames=true
...
scala> spark.sql("select table1.*, table2.`^(?!NAME$).*$` from table1 LEFT OUTER JOIN table2 ON table1.NAME = table2.NAME").show()
+---+----+----------+
| ID|NAME|ACTUALNAME|
+---+----+----------+
|  1| har|     HARRY|
|  2| ron|    RONALD|
|  3|fred|      null|
+---+----+----------+

Здесь

table2.`^(?!NAME$).*$`

разрешает все столбцы table2, кроме NAME. Любое правильное регулярное выражение Java должно работать.

0 голосов
/ 31 октября 2019

мы можем выбрать обязательные поля в запросе sql, как показано ниже

spark.sql("select A.ID,A.NAME,B.ACTUALNAME from table1 A LEFT OUTER JOIN table2 B ON table1.NAME = table2.NAME").show()
0 голосов
/ 31 октября 2019

Если вы не примените псевдоним к фрейму данных, вы получите сообщение об ошибке после создания вашего присоединенного фрейма данных. Если два столбца названы одинаково, ссылка на один из дублированных именованных столбцов возвращает ошибку, которая, по сути, говорит о том, что он не знает, какой из них вы выбрали (неоднозначный). В SQL Server и других языках механизм SQL не позволял бы выполнить этот запрос или автоматически добавлял бы префикс или суффикс к этому имени поля.

...