如何将数据集与其他值之间的值联接?

时间:2018-11-20 19:49:08

标签: apache-spark apache-spark-sql

我有一个用例,需要连接2个数据帧。

ID视图

ID  BookTime
1   2
1   5
2   8
2   3
3   4

FareRule视图

Start End Fare
1   3   10
3   6   20
6   10  25

输出是通过检查BookTime表中的ID进行联接的结果。 Fare是根据StartEndFareRule之间的窗口计算的。

ID  FareDue
1   10
1   20
2   25
2   20
3   20

我正在从这些数据框中创建一个视图,并使用CROSS JOIN将它们联接在一起。但是,正如我们所知,CROSS连接非常昂贵,因此有更好的连接方法吗?

SELECT 
    ID, 
    Fare AS FareDue 
FROM 
    ID 
CROSS JOIN 
    FareRule 
WHERE 
   BookTime >=Start 
   AND 
   BookTime< End

1 个答案:

答案 0 :(得分:-1)

给出以下数据集:

val id = Seq((1, 2), (1, 5), (2, 8), (2, 3), (3, 4)).toDF("ID", "BookTime")
scala> id.show
+---+--------+
| ID|BookTime|
+---+--------+
|  1|       2|
|  1|       5|
|  2|       8|
|  2|       3|
|  3|       4|
+---+--------+

val fareRule = Seq((1,3,10), (3,6,20), (6,10,25)).toDF("start", "end", "fare")
scala> fareRule.show
+-----+---+----+
|start|end|fare|
+-----+---+----+
|    1|  3|  10|
|    3|  6|  20|
|    6| 10|  25|
+-----+---+----+

您只需使用join表达式将它们between一起{}。

val q = id.join(fareRule).where('BookTime between('start, 'end)).select('id, 'fare)
scala> q.show
+---+----+
| id|fare|
+---+----+
|  1|  10|
|  1|  20|
|  2|  25|
|  2|  10|
|  2|  20|
|  3|  20|
+---+----+

您可能需要调整between,使边界在一侧是排他的。默认情况下,between使用下限和上限。