如何在SELECT子句中调用另一表的case表达式并执行计算
问题描述
我有一张仅含一条记录的表T1,其中存储着每日生成的长case when语句。现在需要创建表T2,使用T1中的case表达式填充其某一列。
尝试过的方法(未达预期)
我用了下面的SQL,但COL3列只填充了case表达式的字符串内容,没有执行表达式得到结果:
CREATE TABLE T2 AS SELECT COL1, COL2, T1.CASE_EXPRESSION AS COL3, -- 希望这里用另一张表中的CASE表达式执行后的值 COL4 FROM SOURCE_TABLE FULL OUTER JOIN T1 ON 1=1
当前结果
+-----+------+------------+------+ |COL1 | COL2 | COL3 | COL4 | +-----+------+------------+------+ | V1 | V11 |CASE WHEN...| V23 | +-----+------+------------+------+ | V2 | V12 |CASE WHEN...| V34 | +-----+-------------------+------+
预期结果
COL3应该填充case表达式执行后的结果:
+-----+------+------------+------+ |COL1 | COL2 | COL3 | COL4 | +-----+------+------------+------+ | V1 | V11 | v21 | V23 | +-----+------+------------+------+ | V2 | V12 | v23 | V34 | +-----+-------------------+------+
其他尝试的问题
我用Python执行SQL脚本,也曾尝试在Snowflake中用SET变量存储该case表达式,但表达式过长超出限制:
SET case_expression = (生成case语句的SQL)
请问如何实现需求?
解决方案
Snowflake无法直接执行字符串形式的SQL片段,必须通过动态SQL实现,以下两种方法都可以满足需求:
方法1:Python拼接动态SQL执行
通过Python先读取T1中的case表达式,再拼接到创建T2的SQL中执行:
import snowflake.connector # 建立Snowflake连接 conn = snowflake.connector.connect( user='你的用户名', password='你的密码', account='你的账户名', warehouse='你的仓库', database='你的数据库', schema='你的Schema' ) cursor = conn.cursor() # 1. 读取T1中的CASE表达式 cursor.execute("SELECT CASE_EXPRESSION FROM T1") case_expr = cursor.fetchone()[0] # 2. 拼接创建T2的动态SQL create_t2_sql = f""" CREATE TABLE T2 AS SELECT COL1, COL2, {case_expr} AS COL3, COL4 FROM SOURCE_TABLE """ # 3. 执行动态SQL cursor.execute(create_t2_sql) conn.commit() # 关闭连接 cursor.close() conn.close()
方法2:Snowflake存储过程实现
直接在Snowflake中编写存储过程,完成动态SQL的拼接与执行:
CREATE OR REPLACE PROCEDURE CREATE_T2_WITH_DYNAMIC_CASE() RETURNS VARCHAR LANGUAGE JAVASCRIPT AS $$ // 读取T1中的CASE表达式 var getCaseStmt = "SELECT CASE_EXPRESSION FROM T1"; var caseResult = snowflake.execute({sqlText: getCaseStmt}); caseResult.next(); var caseExpr = caseResult.getColumnValue(1); // 拼接并执行创建T2的SQL var createT2Stmt = ` CREATE TABLE T2 AS SELECT COL1, COL2, ${caseExpr} AS COL3, COL4 FROM SOURCE_TABLE `; snowflake.execute({sqlText: createT2Stmt}); return "表T2创建成功"; $$; // 调用存储过程 CALL CREATE_T2_WITH_DYNAMIC_CASE();
注意事项
- 确保T1中的case表达式语法完全正确,否则拼接后的SQL会执行失败
- 如果case表达式包含单引号,Python拼接时需要注意转义,或确保表达式本身是合法的SQL语句
- 存储过程中使用JavaScript模板字符串时,同样要保证表达式的语法正确性
内容的提问来源于stack exchange,提问作者palamuGuy
相关产品推荐
相关产品推荐

