首页 > 解决方案 > 使用数据框模拟 SQL 更新语句 - 可能吗?

问题描述

在 pyspark 中,我有两个数据框,我想使用它们来模拟 SQL 更新语句。

这是我试图模拟的 sql 代码:

update T1
    set name = (
        select T2.NAME
        from T2
        where
            T2.ID = T1.ID
        )
    where
        T1.END_DATE = '31-dec-1999'
    and exists (
            select
                ID
            from T2
            where
                T2.ID = T1.ID
        )

这是数据帧的一些设置代码

valuesA = [('tom',1,'31-dec-1999'),('dick',2,'01-apr-2017'),('harry',3,'01-jan-2019'),('george',4,'31-dec-1999')]
T1 = spark.createDataFrame(valuesA,['name','id','end_date'])
T1.createOrReplaceTempView("T1")
valuesB = [('fred',1),('james',2),('nigel',4)]
T2 = spark.createDataFrame(valuesB,['name','id'])
T2.createOrReplaceTempView("T2")

spark.sql("select * from T1").show()
spark.sql("select * from T2").show()

上面的输出

+------+---+-----------+
|  name| id|   end_date|
+------+---+-----------+
|   tom|  1|31-dec-1999|
|  dick|  2|01-apr-2017|
| harry|  3|01-jan-2019|
|george|  4|31-dec-1999|
+------+---+-----------+

+-----+---+
| name| id|
+-----+---+
| fred|  1|
|james|  2|
|nigel|  4|
+-----+---+

所需的输出是

+------+---+-----------+
|  name| id|   end_date|
+------+---+-----------+
|  fred|  1|31-dec-1999|
|  dick|  2|01-apr-2017|
| harry|  3|01-jan-2019|
| nigel|  4|31-dec-1999|
+------+---+-----------+

这是我到目前为止所拥有的

from pyspark.sql import functions as f

T1.alias('a').join(
    T2.alias('b'), ['id'], how='outer'
).select('id', 'end_date',
    f.coalesce('b.name', 'a.name').alias('name')
).show()

它的输出

+---+-----------+-----+
| id|   end_date| name|
+---+-----------+-----+
|  1|31-dec-1999| fred|
|  3|01-jan-2019|harry|
|  2|01-apr-2017|james|
|  4|31-dec-1999|nigel|
+---+-----------+-----+

我不确定如何仅在 T1 上的 end_date 为 1999 年 12 月 31 日时进行更新,即第 2 行的名称字段应保持“迪克”

标签: dataframepysparksql-update

解决方案


试试这个:

import pyspark.sql.functions as f
from pyspark.sql.functions import lit, col, when

T1.alias('a').join(
    T2.alias('b'), ['id'], how='outer'
).select('id', 'end_date',
    f.when(f.col("end_date")==lit("31-dec-1999"), f.coalesce(f.col('b.name'), f.col('a.name'))).otherwise(f.col('a.name')).alias('name')
).show()

推荐阅读