【问题标题】:Strings concatenation in Spark SQL querySpark SQL 查询中的字符串连接
【发布时间】:2014-12-07 23:46:00
【问题描述】:

我正在试验 Spark 和 Spark SQL,我需要在一个字符串字段的开头连接一个值,我从一个选择(使用连接)中检索该字段作为输出,如下所示:

val result = sim.as('s)   
    .join(
        event.as('e),
        Inner,
        Option("s.codeA".attr === "e.codeA".attr))   
    .select("1"+"s.codeA".attr, "e.name".attr)  

假设我的表格包含:

模拟

codeA,codeB
0001,abcd
0002,efgh

事件

codeA,name
0001,freddie
0002,mercury

我想作为输出:

10001,freddie
10002,mercury

在 SQL 或 HiveQL 中,我知道我有可用的 concat 函数,但 it seems Spark SQL 不支持此功能。有人可以建议我解决我的问题吗?

谢谢。

注意: 我正在使用语言集成查询,但在最终解决方案的情况下,我可以只使用“标准”Spark SQL 查询。

【问题讨论】:

  • 我认为你不需要做很多工作,比如使用 map 和创建函数。只需使用这个 "val result = sim.as("s").join(events, sim(" codeA")===events("codeA"),"inner") .select("s.codeA","name").withColumn("codeA",concat(lit("1"),lit("" ),col("codeA"))).show "

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


【解决方案1】:

如果我理解正确的话,您最后添加的输出似乎不是您的选择或 SQL 逻辑的一部分。为什么不进一步格式化输出流?

val results = sqlContext.sql("SELECT s.codeA, e.code FROM foobar")
results.map(t => "1" + t(0), t(1)).collect()

【讨论】:

  • 嗨@huitseeker,感谢您的回答。您的解决方案实际上可能是一个选项,因为我确实必须将输出格式化为制表符分隔值。但是,问题仍然存在,因为我还需要使用“连接值”执行另一个连接,即:Option("s.codeA".attr === 1+"r.codeA".attr) 其中 r 的 codeA 值如 10001、10002、...
【解决方案2】:

直接在您的项目中实现新的Expression 类型相对容易。这是我正在使用的:

case class Concat(children: Expression*) extends Expression {
  override type EvaluatedType = String

  override def foldable: Boolean = children.forall(_.foldable)
  def nullable: Boolean = children.exists(_.nullable)
  def dataType: DataType = StringType

  def eval(input: Row = null): EvaluatedType = {
    children.map(_.eval(input)).mkString
  }
}

val result = sim.as('s)
    .join(
        event.as('e),
        Inner,
        Option("s.codeA".attr === "e.codeA".attr))
    .select(Concat("1", "s.codeA".attr), "e.name".attr)

【讨论】:

    猜你喜欢
    • 2014-11-14
    • 2019-01-21
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多