编写查询以根据时间戳条件从Spark中的两个文件中获取记录

时间:2018-03-05 12:54:29

标签: scala apache-spark apache-spark-sql

FileA有这样的数据,其中开始和结束时间戳记作为最后两列

dataa, data1, 9:10, 9:15
datab, data2, 10:00, 10:10
datac, data3, 11:20, 11:30
datad, data4, 12:30, 12:40

FileB有这样的数据,其中开始和结束时间戳记作为最后两列

dataaa, data11, 9:13, 9:17
databb, data22, 10:02, 10:08
datacc, data33, 6:20, 6:30
datadd, data44, 12:31, 12:35

在这两个文件之间执行连接,这应该来自FileB,

databb, data22, 10:02, 10:08
datadd, data44, 12:31, 12:35

连接的条件是FileB的开始时间应该大于FileA的开始时间,而FileB的结束时间应该小于FileA的开始时间。

如何在spark-sql中编写代码。?

1 个答案:

答案 0 :(得分:0)

您可以为这两个文件创建公共schema,因为两个文件的结构相同。

val schema = StructType(Array("col1", "col2", "start", "end").map(StructField(_, StringType, true)))

然后您可以将第一个文件读取为数据框

val fileAdf = sqlContext.read.format("path to fileA")

//+-----+------+------+------+
//|col1 |col2  |start |end   |
//+-----+------+------+------+
//|dataa| data1| 9:10 | 9:15 |
//|datab| data2| 10:00| 10:10|
//|datac| data3| 11:20| 11:30|
//|datad| data4| 12:30| 12:40|
//+-----+------+------+------+

同样,您可以读取第二个文件(fileB)

val fileBdf = sqlContext.read.format("path to fileB")
//+------+-------+------+------+
//|col1  |col2   |start |end   |
//+------+-------+------+------+
//|dataaa| data11| 9:13 | 9:17 |
//|databb| data22| 10:02| 10:08|
//|datacc| data33| 6:20 | 6:30 |
//|datadd| data44| 12:31| 12:35|
//+------+-------+------+------+

使用与 spark-sql 中的问题相同的逻辑

import org.apache.spark.sql.functions._
fileBdf.as("fileB").join(fileAdf.as("fileA"), col("fileB.start") > col("fileA.start") && col("fileB.end") < col("fileA.end"))
  .select(col("fileB.col1"), col("fileB.col2"), col("fileB.start"), col("fileB.end"))

应该给你

+------+-------+------+------+
|col1  |col2   |start |end   |
+------+-------+------+------+
|databb| data22| 10:02| 10:08|
|datadd| data44| 12:31| 12:35|
+------+-------+------+------+

我希望答案很有帮助