使用SQL DATE函数时SparkSQL错误

时间:2015-09-23 15:13:30

标签: sql scala apache-spark apache-spark-sql

在Spark中我试图在一个临时表上执行SQL查询,该临时表是通过读取csv文件并将列转换为正确的数据类型手动构建的数据框派生的。

具体来说,我所说的表是[TPC-H规范] [1]中的LINEITEM表。与规范中所述不同,我使用TIMESTAMP而不是DATE,因为我已经读过Spark不支持DATE类型。

在我的单个scala源文件中,在创建数据框并注册名为“lineitem”的临时表之后,我尝试执行以下查询:

val res = sqlContext.sql("SELECT * FROM lineitem l WHERE date(l.shipdate) <= date('1998-12-01 00:00:00');")

当我使用spark-submit提交打包的jar时,我收到以下错误:

  

线程“main”中的异常java.lang.RuntimeException:[1.75]失败:``union''期望但是`;''结果

当我省略分号并执行相同操作时,我收到以下错误:

  

线程“main”中的异常java.util.NoSuchElementException:找不到键:date

Spark版本是1.4.0。

有没有人知道这些查询有什么问题?

[1] http://www.tpc.org/TPC_Documents_Current_Versions/pdf/tpch2.17.1.pdf

2 个答案:

答案 0 :(得分:7)

  1. 传递给SQLContext.sql的SQL查询不应使用分号分隔 - 这是您第一个问题的来源
  2. DATE UDF期望YYYY-MM-DD表单中的日期和DATE('1998-12-01 00:00:00')评估为null。只要timestamp可以转换为DATE,正确的查询字符串如下所示:

    "SELECT * FROM lineitem l WHERE date(l.shipdate) <= date('1998-12-01')"
    
  3. DATE是一个Hive UDF。这意味着您必须使用HiveContext而不是标准SQLContext - 这是您第二个问题的根源。

    import org.apache.spark.sql.hive.HiveContext
    
    val sqlContext = new HiveContext(sc) // where sc is a SparkContext
    
  4. 在Spark&gt; = 1.5中,也可以使用to_date函数:

    import org.apache.spark.sql.functions.{lit, to_date}
    
    df.where(to_date($"shipdate") <= to_date(lit("1998-12-01")))
    

答案 1 :(得分:2)

请尝试hive功能CAST (expression AS toDatatype) 它将expression从一种数据类型更改为其他数据类型 例如CAST ('2016-06-17 00.00.000' AS DATE)会将String转换为日期
 在你的情况下 val res = sqlContext.sql("SELECT * FROM lineitem l WHERE CAST(l.shipdate as DATE) <= CAST('1998-12-01 00:00:00' AS DATE);")

支持的数据类型转换如Hive Casting Dates

中所列