【问题标题】:SPARK SQL - case when thenSPARK SQL - 当时的情况
【发布时间】:2014-09-29 05:10:08
【问题描述】:

我是 SPARK-SQL 的新手。 SPARK SQL 中是否有等效于“CASE WHEN 'CONDITION' THEN 0 ELSE 1 END”?

select case when 1=1 then 1 else 0 end from table

谢谢 斯里达尔

【问题讨论】:

标签: sql apache-spark


【解决方案1】:

在 Spark 1.2.0 之前

支持的语法(我刚刚在 Spark 1.0.2 上试用过)似乎是

SELECT IF(1=1, 1, 0) FROM table

这个最近的线程http://apache-spark-user-list.1001560.n3.nabble.com/Supported-SQL-syntax-in-Spark-SQL-td9538.html 链接到 SQL 解析器源,这可能会或可能不会帮助取决于您对 Scala 的熟悉程度。至少从第 70 行开始的关键字列表(在撰写本文时)应该会有所帮助。

为方便起见,这里是源的直接链接:https://github.com/apache/spark/blob/master/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala

Spark 1.2.0 及更高版本的更新

从 Spark 1.2.0 开始,支持更传统的语法,响应 SPARK-3813:在 test source 中搜索“CASE WHEN”。例如:

SELECT CASE WHEN key = 1 THEN 1 ELSE 2 END FROM testData

更新最新位置以从 SQL 解析器中找出语法

现在可以找到解析器源here

更新更复杂的示例

针对以下问题,现代语法支持复杂的布尔条件。

SELECT
    CASE WHEN id = 1 OR id = 2 THEN "OneOrTwo" ELSE "NotOneOrTwo" END AS IdRedux
FROM customer

您可以在条件中涉及多个列。

SELECT
    CASE WHEN id = 1 OR state = 'MA' 
         THEN "OneOrMA" 
         ELSE "NotOneOrMA" END AS IdRedux
FROM customer

您还可以嵌套 CASE WHEN THEN 表达式。

SELECT
    CASE WHEN id = 1 
         THEN "OneOrMA"
         ELSE
             CASE WHEN state = 'MA' THEN "OneOrMA" ELSE "NotOneOrMA" END
    END AS IdRedux
FROM customer

【讨论】:

  • 如何添加额外的 if 语句,例如扩展 or。 IE。 SELECT CASE WHEN key = 1 or key2 = 1 THEN 1 ELSE 2 END FROM testData
  • @horatio1701d 只要在 testData 中有一个名为 key2 且类型正确的列,您的示例语法就适用于我(在 Spark 2.1.0 上)。我添加了一堆here 的示例,并相应地更新了我的答案。如果您在完成这项工作时遇到问题,您可能需要发布一个新问题并从此处链接到它。
  • @Spiro Michaylov,这是否意味着对于多个 WHEN 子句,我们需要使用 nested CASE WHEN .. ELSE WHEN?
【解决方案2】:

适用于 Spark 2.+ Spark when function

来自文档:

计算条件列表并返回多个可能的结果表达式之一。如果最后没有定义 else ,则为不匹配的条件返回 null。

 // Example: encoding gender string column into integer.

   // Scala:
   people.select(when(people("gender") === "male", 0)
     .when(people("gender") === "female", 1)
     .otherwise(2))

   // Java:
   people.select(when(col("gender").equalTo("male"), 0)
     .when(col("gender").equalTo("female"), 1)
     .otherwise(2))

【讨论】:

  • 感谢埃胡德!我用这种方法用几行代码构建了一个复杂的嵌套查询!
【解决方案3】:

这种语法在 Databricks 中对我有用:

  select 
    org, 
    patient_id,
    case 
      when (age is null) then 'Not Available'
      when (age < 15) then 'Less than 15'
      when (age >= 15 and age < 25) then '15 to 25'
      when (age >= 25 and age < 35) then '25 to 35'
      when (age >= 35 and age < 45) then '35 to 45'
      when (age >= 45) then '45 and Older'
    end as age_range
  from demo

【讨论】:

    【解决方案4】:

    Oracle SQL for SQL Spark 的 decode() 函数类比可以实现如下:

    ​ case
    ​ ​ ​ when exp1 in ('a','b','c')
    ​ ​ ​ ​ then element_at(map('a','A','b','B','c','C'), exp1)
    ​ ​ ​ else exp1
    ​ ​ end
    

    【讨论】:

      【解决方案5】:
      Based on my current production code, this works
      
         val identifierDF = 
         tempIdentifierDF.select(tempIdentifierDF("t_item_account_id"),
         when(tempIdentifierDF("h_description").contains(tempIdentifierDF("t_cusip")),100)
              .when(tempIdentifierDF("h_description").contains(tempIdentifierDF("t_ticker")),100)
              .when(tempIdentifierDF("h_description").contains(tempIdentifierDF("t_isin")),100)
              .when(tempIdentifierDF("h_description").contains(tempIdentifierDF("t_sedol")),100)
              .when(tempIdentifierDF("h_description").contains(tempIdentifierDF("t_valoren")),100)
              .otherwise(0)
              .alias("identifier_in_description_score")
          )
      

      【讨论】:

        【解决方案6】:

        Spark DataFrame API(Python 版本)也可以进行下一个查询:

        df.selectExpr('time', \
           'CASE WHEN (time > 1) THAN time * 1.1 ELSE time END AS updated_time')
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-10-17
          • 1970-01-01
          • 2022-08-18
          • 1970-01-01
          • 1970-01-01
          • 2020-08-09
          • 1970-01-01
          相关资源
          最近更新 更多