我觉得我一定错过了一些明显的东西,但我似乎不能在Spark SQL中动态设置变量值。
假设我有两个表,tableSrc
和tableBuilder
,我正在创建tableDest
。
我一直在尝试
SET myVar FLOAT = NULL
SELECT
myVar = avg(myCol)
FROM tableSrc;
CREATE TABLE tableDest(
refKey INT,
derivedValue FLOAT
);
INSERT INTO tableDest
SELECT
refKey,
neededValue * myVar AS `derivedValue`
FROM tableBuilder
在T-SQL中这样做是微不足道的,微软(DECLARE
... SELECT
)出人意料地获胜。Error in SQL statement: ParseException: mismatched input 'SELECT' expecting <EOF>(line 53, pos 0)
但是我似乎不能将派生值赋给变量以供重用。我尝试了一些变体,但最接近的是将变量赋给select语句的字符串。
请注意,这是从T-SQL中的一个功能齐全的脚本改编的,所以我不会很快将十几个SQL变量拆分出来,用Python spark查询来计算所有这些变量,只是为了在几百行的f字符串中插入{var1}
,{var2}
等。更糟糕的是,如果可能的话,我想避免这种情况。
6条答案
按热度按时间plicqrtu1#
使用的SET命令用于spark.conf get/set,而不是SQL查询的变量
对于SQL查询,您应该使用小部件:
https://docs.databricks.com/notebooks/widgets.html
但是,有一种方法可以在SQL上使用spark.conf参数:
%python spark.conf.set('personal.foo','bar')
然后您可以使用:用途:
$sql select * from table where column = '${personal.foo}';
技巧部分是您必须在spark.conf的名称上使用一个“点”(或其他特殊字符),否则SQL单元将期望您在运行时为$变量提供值(在我看来这是一个bug,我相信用{}舍入应该足够了)
b91juud32#
Databricks刚刚发布了SQL user defined functions,它可以处理类似的问题,而不会带来性能损失,对于您的示例,它看起来如下所示:
然后是用途:
svujldwt3#
我已经围绕这个问题很长一段时间。最后,我找到了一个使用@Ronieri Marques解决方案和一些pyspark函数的解决方案。我将尝试在下面提供完整的工作代码:
首先创建一个示例表:
结合sqlContext + toJSON,可以动态地为变量赋值,在这种情况下,我使用查询:
最后,可以在SQL查询中使用变量:
注意,子字符串result.first()[14:24]和result.first()[39:49]是必需的,因为result.first()的值是*{“max(date)":“2021-01-03”,“min(date)":“2021-01-01”}*,所以我们需要“定制”最终结果,只选取我们需要的值。
也许代码可以被润色,但现在它是我唯一能实现的工作解决方案。
我希望这个解决方案能对某人有用。
iqxoj9l94#
Databricks现在也有SQL小部件https://docs.databricks.com/notebooks/widgets.html#widgets-in-sql
n8ghc7c15#
在变量赋值的末尾缺少一个分号。
希望有帮助:)
esyap4oy6#
现在支持declare和set语法,但仅在databricks runtime 14.1及更高版本上支持