SparkSQL:我可以在同一个查询中分解两个不同的变量吗?

Eda*_*ame 8 apache-spark apache-spark-sql spark-dataframe

我有以下爆炸查询,工作正常:

data1 = sqlContext.sql("select explode(names) as name from data")
Run Code Online (Sandbox Code Playgroud)

我想爆炸另一个领域"颜色",所以最终输出可能是名称和颜色的笛卡尔积.所以我做了:

data1 = sqlContext.sql("select explode(names) as name, explode(colors) as color from data")
Run Code Online (Sandbox Code Playgroud)

但是我得到了错误:

 Only one generator allowed per select but Generate and and Explode found.;
Run Code Online (Sandbox Code Playgroud)

有谁有想法吗?


我实际上可以通过两个步骤使其工作:

   data1 = sqlContext.sql("select explode(names) as name from data")
   data1.registerTempTable('data1')
   data1 = sqlContext.sql("select explode(colors) as color from data1")
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有可能一步到位?非常感谢!

Sim*_*Sim 21

正确的语法是

select name, color 
from data 
lateral view explode(names) exploded_names as name 
lateral view explode(colors) exploded_colors as color
Run Code Online (Sandbox Code Playgroud)

Rashid的答案不起作用的原因是它没有"命名"生成的表LATERAL VIEW.

说明

可以这样想:它LATERAL VIEW就像一个隐含的JOIN,带有一个临时表structs,为集合中的每一行创建"被查看".所以,解析语法的方法是:

LATERAL VIEW table_generation_function(collection_column) table_name AS col1, ...
Run Code Online (Sandbox Code Playgroud)

多个输出列

如果你使用表生成函数,posexplode()那么你仍然有一个输出表,但有多个输出列:

LATERAL VIEW posexplode(orders) exploded_orders AS order_number, order
Run Code Online (Sandbox Code Playgroud)

嵌套

您也可以LATERAL VIEW通过反复爆炸嵌套集合来"嵌套" ,例如,

LATERAL VIEW posexplode(orders) exploded_orders AS order_number, order
LATERAL VIEW posexplode(order.items) exploded_items AS item_number, item
Run Code Online (Sandbox Code Playgroud)

性能考虑因素

虽然我们的主题LATERAL VIEW是重要的是要注意通过SparkSQL使用它比通过DataFrameDSL 使用它更有效,例如,myDF.explode().原因是SQL可以准确地推断出模式,而DSL API必须在语言类型和数据帧行之间执行类型转换.但是,在性能方面,DSL API会失败,因为您可以从中返回任何支持的类型explode,从而获得灵活性,这意味着您可以在一个步骤中执行更复杂的转换.


小智 6

尝试用侧视图分解代替。

select name, color from data lateral view explode(names) as name lateral view explode(colors) as color;
Run Code Online (Sandbox Code Playgroud)