代码之家  ›  专栏  ›  技术社区  ›  Jacek Laskowski

为什么array\u在SQL中包含两个参数的accept列,但在Dataset API中不包含?

  •  5
  • Jacek Laskowski  · 技术社区  · 6 年前

    我一直在复习关于 array_contains (和 isin )方法,但我仍然无法回答以下问题:

    为什么 array\u包含 在SQL中,是否接受列(引用)作为其参数,而标准函数不接受?

    我可以理解,上述问题很容易被标记为“主要基于意见”或类似问题,因此让我将其重新表述为:

    如何使用 array\u包含 标准函数,以便它接受列中的参数(值)?

    scala> spark.version
    res0: String = 2.3.0
    
    val codes = Seq(
      (Seq(1, 2, 3), 2),
      (Seq(1), 1),
      (Seq.empty[Int], 1),
      (Seq(2, 4, 6), 0)).toDF("codes", "cd")
    scala> codes.show
    +---------+---+
    |    codes| cd|
    +---------+---+
    |[1, 2, 3]|  2|
    |      [1]|  1|
    |       []|  1|
    |[2, 4, 6]|  0|
    +---------+---+
    
    // array_contains in SQL mode works with arguments being columns
    val q = codes.where("array_contains(codes, cd)")
    scala> q.show
    +---------+---+
    |    codes| cd|
    +---------+---+
    |[1, 2, 3]|  2|
    |      [1]|  1|
    +---------+---+
    
    // array_contains standard function with Columns does NOT work. Why?!
    // How to change it so it would work (without reverting to SQL expr)?
    scala> val q = codes.where(array_contains($"codes", $"cd"))
    java.lang.RuntimeException: Unsupported literal type class org.apache.spark.sql.ColumnName cd
      at org.apache.spark.sql.catalyst.expressions.Literal$.apply(literals.scala:77)
      at org.apache.spark.sql.functions$.array_contains(functions.scala:2988)
      ... 49 elided
    
    2 回复  |  直到 6 年前
        1
  •  5
  •   RussS    6 年前

    因为基础函数ArrayContains expr 争论你总是可以欺骗一点。

    scala> codes.where(new Column(ArrayContains($"codes".expr, $"cd".expr))).show
    +---------+---+
    |    codes| cd|
    +---------+---+
    |[1, 2, 3]|  2|
    |      [1]|  1|
    +---------+---+
    **/
    

    正如user9812147所说,这里的问题只是SQL解析器能够访问 ArrayContains 直接起作用。虽然直接函数调用似乎强制将“values”部分视为文本。

        2
  •  5
  •   user9812147 user9812147    6 年前

    只是因为没有人关心实施 (Column, Column) => Column 变种如果您检查源代码,您将看到设计中没有任何内容禁止您创建源代码,因为标准工作流是转换非- Column 文字的参数。

    它甚至不是特别有特色。还有其他一些函数没有包装器 参数,包括但不限于不同的日期/时间处理函数和数学函数。