如何在 Spark SQL 中使用连字符转义列名

Posted

技术标签:

【中文标题】如何在 Spark SQL 中使用连字符转义列名【英文标题】:How to escape column names with hyphen in Spark SQL 【发布时间】:2015-06-17 11:00:02 【问题描述】:

我在 Spark 中导入了一个 json 文件,并将其转换为表格

myDF.registerTempTable("myDF")

然后我想在这个结果表上运行 SQL 查询

val newTable = sqlContext.sql("select column-1 from myDF")

但是,由于column-1 列名称中的连字符,这给了我一个错误。我该如何解决这是 Spark SQL?

【问题讨论】:

尝试用单引号将它们转义 sqlContext.sql("select 'column-1' from myDF") 这不起作用,因为它将'column-1'视为字符串而不是列名。 SQL-99 标准规定双引号 (") 用于分隔标识符。尝试使用双引号,也许将外部的单引号保持在单引号中 """select "column-1" from myDF"""运行查询 【参考方案1】:

反引号 (`) 似乎有效,所以

val newTable = sqlContext.sql("select `column-1` from myDF")

至少在 Spark v1.3.x 中应该可以解决问题。

【讨论】:

【参考方案2】:

昨天研究了一下,结果发现有一种方法可以像这样逃避 (:) 和 (.):

只有包含 (:) 的字段需要用反引号转义

sqlc.select("select `sn2:AnyAddRq`.AnyInfo.noInfo.someRef.myInfo.someData.Name AS sn2_AnyAddRq_AnyInfo_noInfo_someRef_myInfo_someData_Name from masterTable").show()

【讨论】:

【参考方案3】:

我不能发表评论,因为我的次数少于 50 次

当您使用 struct.struct.field 引用 json 结构并且存在如下命名空间时:

ns2:struct.struct.field 反引号(`) 不起作用。

jsonDF = sqlc.read.load('jsonMsgs', format="json")
jsonDF.registerTempTable("masterTable")
sqlc.select("select `sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData.Name` AS sn2_AnyAddRq_AnyInfo_noInfo_someRef_myInfo_someData_Name from masterTable").show()

pyspark.sql.utils.AnalysisException: u"cannot resolve 'sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData.Name'

如果我删除 sn2: 字段,则执行查询。

我也尝试过使用单引号 (')、反斜杠 (\) 和双引号 ("")

如果我在 sn2: 结构上注册另一个临时表,它的唯一工作方式,我可以像这样访问其中的字段

anotherDF = jsonDF.select("sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData")
anotherDF.registerTempTable("anotherDF")
sqlc.select("select Name from anotherDF").show()

【讨论】:

【参考方案4】:

这就是我所做的,也适用于Spark 3.x

我在我的程序顶部(或某些global scope)定义了函数litCol()

litCols = lambda seq: ','.join(('`'+x+'`' for x in seq)) # Accepts any sequence of strings.

然后根据需要应用它来准备我的文字化SELECT 列。这是一个例子:

>>> UNPROTECTED_COLS = ["RegionName", "StateName", "2012-01", "2012-02"]
>>> LITERALIZED_COLS = litCols(UNPROTECTED_COLS)
>>> print(LITERALIZED_COLS)
`RegionName`,`StateName`,`2012-01`,`2012-02`

此示例中存在问题的column namesYYYY-MM 列,Spark 将解析为表达式,分别导致20112010

【讨论】:

以上是关于如何在 Spark SQL 中使用连字符转义列名的主要内容,如果未能解决你的问题,请参考以下文章

Spark生成包含(SQL LIKE)字符串的列名列表

使用 $ 值 spark sql 调用列

使用 spark sql 重命名 Parquet 文件中列名中的空格

Spark SQL 读取已转义双引号的 JSON 文件

在ASP中SQL语句中表名或列名为啥要加中括号

如何使用 spark 获取 hive 分区列名