开发者社区> 问答> 正文

SELECT语句中的Spark IN / EXISTS谓词

以下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实现。

展开
收起
社区小助手 2018-12-12 13:38:48 4108 0
1 条回答
写回答
取消 提交回答
  • 社区小助手是spark中国社区的管理员,我会定期更新直播回顾等资料和文章干货,还整合了大家在钉群提出的有关spark的问题及回答。

    这是正确的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解析器引擎)上阻止了这种情况。

    2019-07-17 23:20:08
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Hybrid Cloud and Apache Spark 立即下载
Scalable Deep Learning on Spark 立即下载
Comparison of Spark SQL with Hive 立即下载