使用函数时雪花不支持的子查询

时间:2021-05-04 23:54:24

标签: sql snowflake-cloud-data-platform

这是我创建的函数:

imageView

我使用 ROW_NUMBER 函数是因为 RATE_DATE 字段实际上是日期时间,因此每个日期有多个记录。

当我自己调用函数时,它工作正常。但是,当我尝试在视图中使用它时,出现不受支持的子查询类型错误。没有它,视图工作正常。谁能想到我可以做些什么来修复错误或通过重写查询来解决它?

编辑 1:查看代码和确切的错误消息

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)
';

错误信息: SQL 错误 [2031] [42601]:SQL 编译错误: 无法评估不受支持的子查询类型

2 个答案:

答案 0 :(得分:0)

如果将其移至 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;

请注意,我更改了参数的名称,因此它们更明显是输入参数。

答案 1 :(得分:0)

错误是相关子查询,不支持(除了一些小玩具示例)

但基本形式是

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 不会为您自动翻译子查询的原因是它很容易出错,而且他们目前正在那里花费开发工作来研究根本不存在的功能等,并且可以通过以下方式重写你,前提是你了解你的模型。