首页 > 解决方案 > 在 Databricks / Spark 中的 SQL 中为变量分配动态值

问题描述

我觉得我必须在这里遗漏一些明显的东西,但我似乎无法在 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 中这样做是微不足道的,这对 Microsoft 来说是一个令人惊讶的胜利 ( DECLARE... SELECT)。然而,Spark 会抛出

Error in SQL statement: ParseException: mismatched input 'SELECT' expecting <EOF>(line 53, pos 0)

但我似乎无法将派生值分配给变量以供重用。我尝试了一些变体,但最接近的是将变量分配给 select 语句的字符串。

数据块屏幕截图

请注意,这是从 T-SQL 中的功能齐全的脚本改编而来的,因此我不会立即拆分十几个 SQL 变量来使用 Python spark 查询来计算所有这些变量,只是为了插入{var1}{var2}等一个数百行的 f 弦。我知道如何做到这一点,但它会很混乱、困难、难以阅读、迁移速度较慢、维护起来也更糟,如果可能的话,我想避免这种情况

标签: apache-sparkapache-spark-sqlpyspark-sqldatabricks

解决方案


使用的SET命令用于 spark.conf 获取/设置,而不是用于 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 单元会期望您在运行时为 $variable 提供值(看起来像一个错误对我来说,我相信用 {} 四舍五入就足够了)


推荐阅读