Sql 在PySpark中使用日期进行滚动联接?

Sql 在PySpark中使用日期进行滚动联接?,sql,apache-spark,pyspark,apache-spark-sql,Sql,Apache Spark,Pyspark,Apache Spark Sql,我试图在两个PySpark数据帧之间进行连接,在一个键上连接,但是第一个表的日期应该总是在第二个表的日期之后。举个例子。我们正在尝试加入两个表: 表1: Date1 value1 key 13 Feb 2020 1 a 01 Mar 2020 2 a 31 Mar 2020 3 a 15 Apr 2020 4 a 表2: Date2 value2 key 10 Feb 2020 11

我试图在两个PySpark数据帧之间进行连接,在一个键上连接,但是第一个表的日期应该总是在第二个表的日期之后。举个例子。我们正在尝试加入两个表:

表1:

    Date1    value1   key
13 Feb 2020    1       a
01 Mar 2020    2       a
31 Mar 2020    3       a
15 Apr 2020    4       a
表2:

    Date2    value2  key
10 Feb 2020    11     a
15 Mar 2020    22     a
连接后,结果应如下所示:

    Date1    value1 value2  key
13 Feb 2020    1      11     a
01 Mar 2020    2     null    a
31 Mar 2020    3      22     a
15 Apr 2020    4     null    a

有什么想法吗?

这是一个有趣的加入。我的方法是先按键连接,选择最早的日期,然后在找到最早的日期后进行自连接

from pyspark.sql import functions as F, Window

# Clean up date format first
df3 = df1.withColumn('Date1', F.to_date('Date1', 'dd MMM yyyy'))
df4 = df2.withColumn('Date2', F.to_date('Date2', 'dd MMM yyyy'))

result = (df3.join(df4, 'key')
             .filter('Date1 > Date2')
             .withColumn('rn', F.row_number().over(Window.partitionBy('Date2').orderBy('Date1')))
             .filter('rn = 1')
             .drop('key', 'rn', 'Date2')
             .join(df3, ['Date1', 'value1'], 'right')
         )

result.show()
+----------+------+------+---+
|Date1     |value1|value2|key|
+----------+------+------+---+
|2020-02-13|1     |11    |a  |
|2020-03-01|2     |null  |a  |
|2020-03-31|3     |22    |a  |
|2020-04-15|4     |null  |a  |
+----------+------+------+---+

您可以尝试窗口滞后函数,它是scala,但python版本将类似

// change col names for union all and add extra col to indentify dataset
val df1A = df1.toDF("Date","value","key").withColumn("df",lit(1))
val df2A = df2.toDF("Date","value","key").withColumn("df",lit(2))

import org.apache.spark.sql.expressions.Window

df1A.unionAll(df2A) 
.withColumn("value2",lag(array('value,'df),1) over Window.partitionBy('key).orderBy(to_date('Date,"dd MMM yyyy")))
.filter('df===1)
.withColumn("value2",when(element_at('value2,2)===2,element_at('value2,1)))
.drop("df")
.show
输出:

+-----------+-----+---+------+
|       Date|value|key|value2|
+-----------+-----+---+------+
|13 Feb 2020|    1|  a|    11|
|01 Mar 2020|    2|  a|  null|
|31 Mar 2020|    3|  a|    22|
|15 Apr 2020|    4|  a|  null|
+-----------+-----+---+------+

这是非常复杂的。。。有没有办法避免按值2分组?实际案例有更多的列,value2只是一个示例。为什么我们要按值2分组?@eRendil这是因为我们想匹配与每个日期2/value2对应的最早日期1。谢谢。我的F模块似乎没有数组_min。这似乎是一个较新的功能。没有它我还能做什么?@Ehrendil我已经清理了我的答案。不再有分组依据值2,也不再有数组_min。请让我知道它是否有效!花了一段时间使其适应我的实际用例,但这非常有效。非常感谢。