Snowflake 不支持 UDTF 子查询类型

问题描述 投票:0回答:1

在 Snowflake 中,我试图通过创建一个 UDTF 来根据

v
x
中是否存在符合某种模式的行来显示每行
y
的标志,从而节省大量代码大小和维护成本。

我得到的错误是

SQL Error [2031] [42601]: SQL compilation error: Unsupported subquery type cannot be evaluated

这是一些最小的示例代码:

DROP TABLE IF EXISTS v;
CREATE TABLE v (CHARTGUID NUMBER(16));
INSERT INTO v VALUES(1410522400170);
INSERT INTO v VALUES(1548089000170);

DROP TABLE IF EXISTS x;
CREATE TABLE x (CHARTGUID NUMBER(16), FOO INT, BAR VARCHAR(1));
INSERT INTO x(CHARTGUID, FOO, BAR) VALUES (1410522400170, 1, 'a');
INSERT INTO x(CHARTGUID, FOO, BAR) VALUES (1548089000170, 0, 'a');

DROP TABLE IF EXISTS y;
CREATE TABLE y (CHARTGUID NUMBER(16), FOO INT, BAR VARCHAR(1));
INSERT INTO y(CHARTGUID, FOO, BAR) VALUES (1410522400170, 0, 'a');
INSERT INTO y(CHARTGUID, FOO, BAR) VALUES (1548089000170, 1, 'a');
INSERT INTO y(CHARTGUID, FOO, BAR) VALUES (1548089000170, 1, 'b');

CREATE OR REPLACE FUNCTION TEST_C(CHART_GUID NUMBER, p VARCHAR)
   RETURNS TABLE(A INT, B INT)
AS
$$
   SELECT
      CASE WHEN EXISTS (
         SELECT x.CHARTGUID
         FROM x
         WHERE x.CHARTGUID = CHART_GUID
            AND x.FOO = 1
            AND x.BAR = p
      ) THEN 1 ELSE 0 END,
      CASE WHEN EXISTS (
         SELECT y.CHARTGUID
         FROM y
         WHERE y.CHARTGUID = CHART_GUID
            AND y.FOO = 1
            AND y.BAR = p
      ) THEN 1 ELSE 0 END,
$$
;

SELECT
   v.CHARTGUID,
   x.*
FROM v,
   TABLE(TEST_C(v.CHARTGUID, 'a')) x

真正的用例有很多

TABLE(TEST_C(v.CHARTGUID, 'a'))
,其中
'a'
是一个正则表达式模式,需要针对每个模式检查它在两个表
x
y
中的存在。

雪花“子查询限制”的解决方法是什么?

sql snowflake-cloud-data-platform subquery user-defined-functions correlated-subquery
1个回答
0
投票

所以表格可以用不同的方式写,我觉得更干净,因为字符更少,因此更具可读性,并且它们是原子操作:

CREATE or replace TABLE v (CHARTGUID number) 
    as select * from values
        (1410522400170),
        (1548089000170);

CREATE or replace TABLE x (CHARTGUID number, FOO number, BAR text)
    as select * from values
        (1410522400170, 1, 'a'),
        (1548089000170, 0, 'a');

CREATE or replace TABLE y (CHARTGUID number, FOO number, BAR text)
    as select * from values
        (1410522400170, 0, 'a'),
        (1548089000170, 1, 'a'),
        (1548089000170, 1, 'b');

我倾向于预处理数据,以便它可以与 CTE 等连接基(左或正常)

WITH xx as (
    select distinct chartguid
    from x 
    where foo = 1
), yy as (
    select distinct chartguid
    from y
    where foo = 1
)
SELECT
   v.chartguid,
   NVL2(xx.chartguid, 1,0) as x1,
   NVL2(yy.chartguid, 1,0) as x2
FROM v
LEFT JOIN xx 
    on xx.chartguid = v.chartguid
LEFT JOIN yy
    on yy.chartguid = v.chartguid

这不会为您提供“一个隐藏所有工作的巧妙功能”,这通常是一个粗俗的技巧,但如果您需要聪明,您可以创建一个 UDTF,在连接主表之前将这两个+ CTE 连接在一起,但这可能会做工作量太大了。

© www.soinside.com 2019 - 2024. All rights reserved.