以下Spark SQL测试查询:
Seq("france").toDF.createOrReplaceTempView("countries")
SELECT CASE WHEN country = 'italy' THEN 'Italy'
ELSE ( CASE WHEN country IN (FROM countries) THEN upperCase(country) ELSE country END )
END AS country FROM users
这会引发以下错误:
Exception in thread "main" org.apache.spark.sql.AnalysisException:
IN/EXISTS predicate sub-queries can only be used in a Filter
以下是查询的部分CASE WHEN country IN (FROM countries)原因。
是否存在Spark SQL中的任何解决方法以便country IN (FROM countries)在选择条件中进行模拟?我对纯SQL实现感兴趣,而不是通过API实现。
这是正确的SQL查询:
import sparkSession.implicits._
Seq("france").toDF("country").createOrReplaceTempView("countries")
Seq(("user1", "france"), ("user2", "italy"), ("user2", "usa"))
.toDF("user", "country").createOrReplaceTempView("users")
val query =
s"""
|SELECT
| CASE
| WHEN u.country = 'italy' THEN 'Italy'
| ELSE (
| CASE
| WHEN u.country = c.country THEN upper(u.country)
| ELSE u.country
| END
| ) END AS country
|FROM users u
|LEFT JOIN countries c
| ON u.country = c.country
""".stripMargin
sparkSession.sql(query).show()
结果:
country |
---|
FRANCE |
Italy |
usa |
你IN/EXISTS只能在谓词中使用sql操作符的场景背后的原因是:投影CASE-WHEN中的逻辑(在我们的例子中)是对从选择返回的数据集中的每一行进行评估。考虑到这一点,CASE WHEN country IN (SELECT * FROM countries)从users表中为每一行运行等效的并不是最好的主意。因此,SQL在语言级别(sql解析器引擎)上阻止了这种情况。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。