在 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 时,我收到以下错误:
Exception in thread "main" java.lang.RuntimeException: [1.75] failure: ``union'' expected but but `;' found
当我省略分号并做同样的事情时,我收到以下错误:
Exception in thread "main" java.util.NoSuchElementException: key not found: date
Spark 版本为 1.4.0。
有人知道这些查询有什么问题吗?
[1] http://www.tpc.org/TPC_Documents_Current_Versions/pdf/tpch2.17.1.pdf
最佳答案
- 传递给
SQLContext.sql
的 SQL 查询不应使用分号分隔 - 这是您的第一个问题的根源 DATE
UDF 需要 YYYY-MM-DD 形式的日期,而DATE('1998-12-01 00:00:00')
计算结果为空
。只要timestamp
可以转换为DATE
正确的查询字符串如下所示:"SELECT * FROM lineitem l WHERE date(l.shipdate) <= date('1998-12-01')"
DATE
是 Hive UDF。这意味着您必须使用HiveContext
而不是标准的SQLContext
- 这是您的第二个问题的根源。import org.apache.spark.sql.hive.HiveContext val sqlContext = new HiveContext(sc) // where sc is a SparkContext
在 Spark >= 1.5 中也可以使用
to_date
函数:import org.apache.spark.sql.functions.{lit, to_date} df.where(to_date($"shipdate") <= to_date(lit("1998-12-01")))
关于sql - 使用 SQL DATE 函数时的 SparkSQL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32743341/