我有以下问题:
SELECT * FROM t1, t2 WHERE t1.a = 10 AND t2.a > 20 AND t1.b=t2.b
该应用程序已演变为拥有t1.a
,t2.a
,t1.b
和t2.b
数组。
我可以将t1.a = 10
重写为array_contains(t1.a, 10)
,但我无法找到任何有效的受支持的SQL功能,这些功能使我能够重现逻辑比较t2.a > 20
和列内表比较t1.b=t2.b
对数组的影响。
有人可以帮我重写查询吗?它可能需要用户定义的功能吗?
上下文:我使用Spark SQL查询Parquet表。我包含了Hive标记,因为Spark SQL实现了它的许多功能。
答案 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|
+---+----------+-----+