在Scala中,将列表或变量动态传递到spark databricks笔记本中的SQL单元的正确方法是什么?

在Scala中,将列表或变量动态传递到spark databricks笔记本中的SQL单元的正确方法是什么?,scala,apache-spark,apache-spark-sql,databricks,Scala,Apache Spark,Apache Spark Sql,Databricks,这似乎应该是直截了当的做法,但迄今为止,我们还没有能够让这一点在长长的列表中清晰地发挥作用: 前一单元格: val myList = List(111,222) 当前单元格: %sql DROP TABLE IF EXISTS myTable; CREATE TABLE myTable AS SELECT * FROM datalake.someTable t WHERE t.someColumn IN myList --correctly parse the list

这似乎应该是直截了当的做法,但迄今为止,我们还没有能够让这一点在长长的列表中清晰地发挥作用:

前一单元格:

val myList = List(111,222)
当前单元格:

%sql
DROP TABLE IF EXISTS myTable;

CREATE TABLE myTable AS
    SELECT * FROM datalake.someTable t
      WHERE t.someColumn IN myList --correctly parse the list here

一种解决方案可能是使用小部件,但这似乎是针对字符串的,而对于长列表,它将受到最大字符串长度的限制?感谢您的帮助

您可以注册包含变量的用户定义函数。如前所述,用户定义的函数可以传递给SQL单元格

在scala单元格中,您的代码将是:

val myList=List(111222)
val myListUdf=()=>myList
register(“我的列表”,myListUdf)
然后,您可以在SQL单元格中执行查询:

%sql
如果myTable存在,则删除该表;
将表myTable创建为
从datalake.someTable t中选择*
其中数组_包含(my_list(),t.someColumn)

您可以注册包含变量的用户定义函数。如前所述,用户定义的函数可以传递给SQL单元格

在scala单元格中,您的代码将是:

val myList=List(111222)
val myListUdf=()=>myList
register(“我的列表”,myListUdf)
然后,您可以在SQL单元格中执行查询:

%sql
如果myTable存在,则删除该表;
将表myTable创建为
从datalake.someTable t中选择*
其中数组_包含(my_list(),t.someColumn)

感谢Vincent(+1)就我的特殊情况而言,我应该更清楚地回答这个问题-该列是代理项ID,可以是长整数,例如:List(2182361060000,…),这会导致int太大问题,或者如果定义为List(11111111111 L,…),则类型不匹配。该列表将由以下内容创建:val myList=someTable.select(“surr_id”).collect().map((0)).toList,当我尝试将其注册为UDF时,它会抛出一个错误:java.lang.UnsupportedOperationException:不支持Any类型的模式?第一点,要将列转换为Long,可以使用CAST SQL方法,类似于
CAST(代理ID为BIGINT)
。第二点,对于数组,在
收集
之后,使用
.map((0))
创建任何不可由spark序列化的列表。解决方案是使用
.map(u.getLong(0))
。希望能对你有所帮助,非常感谢!!嗨,文森特,对不起,我以为它在那里运行得很好,但是.map(u.getLong(0))抛出:java.lang.ClassCastException:java.math.BigDecimal不能被强制转换为java.lang.Long?你可以在收集数据之前将BigDecimal强制转换为Long:
someTable.select(“surr\u id”).withColumn(“surr\u id”).cast(“Long”).collect().map(u.getLong(0))
。如果这样做,则需要使用导入org.apache.spark.sql.functions.col导入
col
函数。或者您可以在collect之后强制转换为BigDecimal:
.collect().map(u.getAs[java.math.BigDecimal](0))
。这取决于您是想要一个长的列表(第一个解决方案)还是一个大十进制的列表(第二个解决方案)。感谢您(+1)两个额外的参数,就我的特殊情况而言,我应该更清楚地回答这个问题-该列是代理项ID,可以是长整数,例如:list(2182361060000,…)导致int太大问题,或者如果定义为List(11111111111 L,…)则类型不匹配。列表将由以下内容创建:val myList=someTable.select(“surr_id”).collect().map((0)).toList,当我尝试将其注册为UDF时,它会抛出一个错误:java.lang.UnsupportedOperationException:不支持类型Any的模式?第一点,要将列转换为Long,可以使用CAST SQL方法,类似于
CAST(代理ID为BIGINT)
。第二点,对于你的数组,在你的
收集之后,你可以使用
.map(u(0))
来创建一个任何的列表,而不是由spark序列化。解决方法是使用
.map(u.getLong(0))
。希望它能帮助你。非常感谢Vincent!!嗨Vincent,对不起,我认为它在那里运行得很好,但是.map(.getLong(0))抛出:java.lang.ClassCastException:java.math.BigDecimal无法转换为java.lang.Long?您可以在收集数据之前将BigDecimal转换为Long:
someTable.select(“surr\u id”).withColumn(“surr\u id”)、col(“surr\u id”).cast(“Long”).collect().map(\u.getLong(0))
。如果这样做,则需要使用
import org.apache.spark.sql.functions.col
导入
col
函数。或者,您可以在collect之后强制转换为bigdecim:
.collect().map(u.getAs[java.math.bigdecim](0))
。这取决于您想要的是
Long
(第一个解决方案)列表还是
bigdecimic
(第二个解决方案)