SparkSQL / Hive上的数组列比较

时间:2016-03-31 17:22:03

标签: hive apache-spark-sql

我有以下问题:

SELECT * FROM t1, t2 WHERE t1.a = 10 AND t2.a > 20 AND t1.b=t2.b

该应用程序已演变为拥有t1.at2.at1.bt2.b数组。

我可以将t1.a = 10重写为array_contains(t1.a, 10),但我无法找到任何有效的受支持的SQL功能,这些功能使我能够重现逻辑比较t2.a > 20和列内表比较t1.b=t2.b对数组的影响。

有人可以帮我重写查询吗?它可能需要用户定义的功能吗?

上下文:我使用Spark SQL查询Parquet表。我包含了Hive标记,因为Spark SQL实现了它的许多功能。

1 个答案:

答案 0 :(得分:2)

您可以编写自己的UDF进行比较。很简单:

sqlContext.udf.register("arrayGreater", (arr: Seq[Int], x: Int) => {
   arr.toArray.filter(i => i > x).length > 0
})

然后,你就这样使用它:

val df = Seq((1,Array(1,2,3)), (2,Array(7,9,11))).toDF("key", "arr")
df.registerTempTable("DF")

df.show
+---+----------+
|key|       arr|
+---+----------+
|  1| [1, 2, 3]|
|  2|[7, 9, 11]|
+---+----------+

sqlContext.sql("SELECT * from DF where arrayGreater(arr, 10)").show
+---+----------+
|key|       arr|
+---+----------+
|  2|[7, 9, 11]|
+---+----------+

请注意,截至目前,arrayGreater正在返回Boolean。您可以返回Int - 只需返回已过滤的length,而不是检查它是否为> 0

sqlContext.udf.register("arrayCountGreater", (arr: Seq[Int], x: Int) => {
   arr.toArray.filter(i => i > x).length
})

sqlContext.sql("SELECT *, arrayCountGreater(arr, 2) from DF").show
+---+----------+-----+
|key|       arr|count|
+---+----------+-----+
|  1| [1, 2, 3]|    1|
|  2|[7, 9, 11]|    3|
+---+----------+-----+