Sql 使用函数时雪花不支持的子查询
这是我创建的函数:Sql 使用函数时雪花不支持的子查询,sql,snowflake-cloud-data-platform,Sql,Snowflake Cloud Data Platform,这是我创建的函数: CREATE OR REPLACE FUNCTION NS_REPORTS.AP."COUPA_GET_EXCH_RATE"("from_curr_id" NUMBER(38,0), "to_curr_id" NUMBER(38,0), "date" DATE) RETURNS FLOAT LANGUAGE SQL AS ' SELECT COALESCE((
CREATE OR REPLACE FUNCTION NS_REPORTS.AP."COUPA_GET_EXCH_RATE"("from_curr_id" NUMBER(38,0), "to_curr_id" NUMBER(38,0), "date" DATE)
RETURNS FLOAT
LANGUAGE SQL
AS '
SELECT
COALESCE((
SELECT
RATE
FROM
(
SELECT
ROW_NUMBER() OVER (PARTITION BY DATE(RATE_DATE) ORDER BY RATE_DATE DESC) ROW_NUM
, RATE
FROM
CONNECTORS.COUPA.EXCHANGE_RATE
WHERE
FROM_CURRENCY_ID = from_curr_id
AND TO_CURRENCY_ID = to_curr_id
AND DATE(RATE_DATE) = date
) R
WHERE
ROW_NUM = 1
), 1)
';
我使用ROW_NUMBER函数是因为RATE_DATE字段实际上是datetime,因此每个日期都有多条记录
当我单独调用这个函数时,它工作得很好。但是,当我尝试在视图中使用它时,会出现不支持的子查询类型错误。没有它,风景很好。有人能想到我能做些什么来修复错误或通过重写查询来解决它吗
编辑1:查看代码和确切的错误消息
错误消息:
SQL错误[2031][42601]:SQL编译错误:
无法计算不支持的子查询类型如果将其移动到FROM子句,会怎么样?我想这样说:
SELECT COALESCE(MAX(er.rate), 1)
FROM (SELECT er.*
FROM CONNECTORS.COUPA.EXCHANGE_RATE er
WHERE er.FROM_CURRENCY_ID = in_from_curr_id AND
er.TO_CURRENCY_ID = in_to_curr_id AND
DATE(er.RATE_DATE) = in_date
ORDER BY RATE_DATE DESC
LIMIT 1
) er;
请注意,我更改了参数的名称,使它们更明显地成为输入参数。错误是一个相关子查询,除了一些小玩具示例外,不支持 但基本形式是
SELECT a.a
(select b.b from b where b.a = a.a order by b.y limit 1)
FROM a;
实际上,对于每一行,在另一个表上运行一个子查询以获取一个值。在其他数据库中有许多技巧可以实现这一点,但实际上每一行都有工作要做。Snowflake不支持每行操作的类型
好消息是还有其他模式实际上是相同的,雪花确实支持,这两种模式实际上是相同的,使用CTE或连接到子选择,这是相同的事情
因此,上述内容变成:
WITH subquery AS (
SELECT b.a, b.b FROM b
QUALIFY row_number() over (partition by b.a order by b.y) = 1
)
SELECT a.a
sq.b
FROM a
JOIN subquery AS sq
ON sq.a = a.a
因此,我们首先处理/成形来自另一个/子表的所有记录,并且只保留具有所需计数/形状的行,然后连接到该结果。该方法非常可并行,因此性能良好。Snowflake不为您自动翻译子查询的原因是,它很容易出错,而且他们目前正在开发根本不存在的功能,等等,您可以重写它,如果您了解您的模型。我知道雪花错误消息没有多大帮助,但您能否分享您的视图外观以及确切的错误消息是什么?尽管如此,我无法执行MAXer.rate。最大值(如果有)必须在er.rate_日期。否则我会得到最大的利率,而不是最近的利率。@MikeCaputo。子查询只返回一行,因此MAX实际上没有做任何事情。它只保证结果集中有一行。这样做会得到同样的不受支持的子查询类型错误。@MikeCaputo。我在想,把逻辑移到FROM子句可能会解决这个问题。将此标记为答案,因为它与我最终所做的非常相似。谢谢大家的帮助。
WITH subquery AS (
SELECT b.a, b.b FROM b
QUALIFY row_number() over (partition by b.a order by b.y) = 1
)
SELECT a.a
sq.b
FROM a
JOIN subquery AS sq
ON sq.a = a.a