Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pyspark/SQL:添加像left-semi-join这样的标志列_Sql_Apache Spark_Pyspark - Fatal编程技术网

Pyspark/SQL:添加像left-semi-join这样的标志列

Pyspark/SQL:添加像left-semi-join这样的标志列,sql,apache-spark,pyspark,Sql,Apache Spark,Pyspark,例如,数据是 customer=spark.createDataFrame([ (0,“票据室”), (1,“Matei Zaharia”), (2,“迈克尔·阿姆布鲁斯特”)])\ .toDF(“客户ID”、“名称”) order=spark.createDataFrame([ (0,0,“产品0”), (1,1,“产品1”), (2,1,“产品2”), (3,3,“产品3”), (4,1,“产品4”)])\ .toDF(“订单ID”、“客户ID”、“产品名称”) 要获得客户订单,我可以使用

例如,数据是

customer=spark.createDataFrame([
(0,“票据室”),
(1,“Matei Zaharia”),
(2,“迈克尔·阿姆布鲁斯特”)])\
.toDF(“客户ID”、“名称”)
order=spark.createDataFrame([
(0,0,“产品0”),
(1,1,“产品1”),
(2,1,“产品2”),
(3,3,“产品3”),
(4,1,“产品4”)])\
.toDF(“订单ID”、“客户ID”、“产品名称”)
要获得客户订单,我可以使用
left semi

customer.join(订单,['customerid'],“左半”).show()
它可以回来

现在出于比较的原因,我想添加一个标志列,而不是直接过滤掉一些行。所需的输出如下所示:

+----------------+----------------+
|customerid | name |有订单|
+----------+----------------+---------+ 
|0 |比尔·钱伯斯|正确|
|1 | Matei Zaharia |真的|
|2 |迈克尔·阿姆布鲁斯特|错|
+----------+----------------+---------+
我怎么做?有什么优雅的方法吗?我试着搜索,但没有找到相关的东西,也许我得到了错误的关键字



可以使用SQL的exist/in进行此操作:

您可以执行左联接,并根据
orderid
列是否为空来创建
has\u order
列。然后使用
distinct()
删除重复的行

导入pyspark.sql.f函数
customer.alias(“c”).join(order.alias(“o”),on=[“customerid”],how=“left”)\
.选择(
“c.*”,
f、 col(“o.orderid”).isNull().alias(“has_order”)
)\
.distinct()\
.show()
#+----------+----------------+---------+
#|customerid | name |有订单|
#+----------+----------------+---------+
#|0 |比尔·钱伯斯|正确|
#|1 | Matei Zaharia |正确|
#|2 |迈克尔·阿姆布鲁斯特|错|
#+----------+----------------+---------+

如果要使用类似于正在使用的左半联接的内容,可以合并左半联接和左反联接的结果:

cust\u left\u semi=customer.join(订单,['customerid'],“leftsemi”)\
.withColumn('has_order',f.lit(True))
客户左半成品展示()
#+----------+-------------+---------+
#|customerid | name |有订单|
#+----------+-------------+---------+
#|0 |比尔·钱伯斯|正确|
#|1 | Matei Zaharia |正确|
#+----------+-------------+---------+
cust_left_anti=customer.join(订单,['customerid'],“leftanti”)\
.withColumn('has_order',f.lit(False))
客户左防秀()
#+----------+----------------+---------+
#|customerid | name |有订单|
#+----------+----------------+---------+
#|2 |迈克尔·阿姆布鲁斯特|错|
#+----------+----------------+---------+
cust_left_semi.union(cust_left_anti.show)()
#+----------+----------------+---------+
#|customerid | name |有订单|
#+----------+----------------+---------+
#|0 |比尔·钱伯斯|正确|
#|1 | Matei Zaharia |正确|
#|2 |迈克尔·阿姆布鲁斯特|错|
#+----------+----------------+---------+

您可以使用
except
join\u result.except(customer).withColumn(“has\u order”,lit(False))
然后
union
将结果与
join\u result.withColumn(“has\u order”,lit(True))
。或者,您可以选择不同的订单id,然后与
客户
进行左连接,然后在
-
时使用
,否则
nvl
进行填充
的订单
@Philantrover是的……但与
左半部分
的简单性相比,这要复杂得多。@cqcn1991我个人认为join和过滤器是更好的解决方案,但也有
leftsemi
leftanti
联接的
union
选项(请参见我的)。好的,我将尝试对这两个解决方案进行基准测试,并给您一些反馈。而且,是否有可能通过简单的解决方案通过SQL实现结果,因为在SQL中支持IN/Exist?如中所示,SparkSQL AFAIK中目前不支持EXISTS/IN。