Pyspark-案例陈述中的子查询

时间:2018-03-15 00:06:02

标签: python pyspark pyspark-sql

我正在尝试在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

1 个答案:

答案 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)]