我正在尝试在Pyspark中的case语句中运行一个子查询,它正在抛出异常。如果一个表中的id出现在另一个表中,我试图创建一个新标志。
任何人都可以告诉我,如果在pyspark中甚至可以这样做吗?
temp_df=spark.sql("select *, case when key in (select distinct key from Ids) then 1 else 0 end as flag from main_table")
这是错误:
AnalysisException: 'Predicate sub-queries can only be used in a Filter
答案 0 :(得分:4)
This似乎是关于子查询的最新详细文档 - 它与Spark 2.0有关,但从那以后我还没有看到该领域的重大更新。
该引用中的链接笔记本清楚地表明,WHERE子句中当前仅支持谓词子查询。 即这可行(但当然不会产生预期的结果):
public class Product
{
public List<string> Name { get; set; }
}
string json = File.ReadAllText("products.json");
var products = JsonConvert.DeserializeObject<List<Product>>(json);
var result = (from p in products
.GroupBy(pt => pt.Name)
.OrderByDescending(pt => pt.Count())
.SelectMany(pt => pt)
select p).Take(3);
你可以通过左边的JOIN获得相同的结果 - 这是IN子查询通常被翻译成的内容(有关详细信息,请参阅前面提到的链接笔记本)。
例如:
spark.sql("select * from main_table where id in (select distinct id from ids_table)")
或者,使用pyspark sql函数而不是sql语法:
# set up some data
l1 = [('Alice', 1), ('Bob', 2), ('Eve', 3)]
df1 = sql_sc.createDataFrame(l1, ['name', 'id'])
l2 = [(1,), (2,)]
df2 = sql_sc.createDataFrame(l2, ['id'])
df1.createOrReplaceTempView("main_table")
df2.createOrReplaceTempView("ids_table")
# use a left join
spark.sql("select * from main_table m left join ids_table d on (m.id=d.id)") \
.withColumn('flag', func.when(func.col('d.id').isNull(), 0).otherwise(1)) \
.drop('id').collect()
# result:
[Row(name='Bob', flag=1), Row(name='Eve', flag=0), Row(name='Alice', flag=1)]