【问题标题】:Snowflake CROSS JOIN referencing prior table in VALUES clauseSnowflake CROSS JOIN 在 VALUES 子句中引用先前表
【发布时间】:2021-11-11 10:51:14
【问题描述】:

Snowflake CROSS JOIN 是否支持在连接中引用其他表?此语句产生错误:

SQL 编译错误:VALUES 子句中的表达式 [T.ID1] 无效

WITH t AS
(
    SELECT *
    FROM (VALUES
        (1, 2)
    ,   (3, 4)
    ) x(id1, id2)
)
SELECT
    t.*
,   x.*
FROM t
CROSS JOIN (VALUES
    (t.id1)
,   (t.id2)
) x(id3)

这在 MSSQL 中按预期工作(使用 CROSS APPLY 而不是 CROSS JOIN)。

但是,对交叉连接中的值进行硬编码是可行的,但对我的用例来说并不实用:

WITH t AS
(
    SELECT *
    FROM (VALUES
        (1, 2)
    ,   (3, 4)
    ) x(id1, id2)
)
SELECT
    t.*
,   x.*
FROM t
CROSS JOIN (VALUES
    (1)
,   (2)
,   (3)
,   (4)
) x(id3)

它产生了预期的结果:

ID1,ID2,ID3
1,2,1
3,4,1
1,2,2
3,4,2
1,2,3
3,4,3
1,2,4
3,4,4

还有其他方法可以在 Snowflake 中产生所需的结果吗?

【问题讨论】:

    标签: snowflake-cloud-data-platform


    【解决方案1】:

    Snowflake 中没有 CROSS APPLY。

    这足够动态吗?

    WITH t AS
    (
        SELECT *
        FROM (VALUES
            (1, 2)
        ,   (3, 4)
        ) t (id1, id2)
    )
    SELECT
        t.*,
        third_col
    FROM t
    CROSS JOIN (SELECT ID1 as third_col FROM t UNION ALL SELECT ID2 FROM t)
    

    【讨论】:

    • 我喜欢你的回答,但是,我选择了另一个 b/c(虽然没有明确说明)它模仿 MSSQL 的行为。谢谢。
    【解决方案2】:

    Snowflake CROSS JOIN 是否支持在连接中引用其他表?

    是的,这是可能的。 CROSS APPLY/OUTR APPLY 的 ISO SQL 标准对应项称为 LATERAL JOIN。

    WITH t AS (
    SELECT *
        FROM (VALUES
            (1, 2)
        ,   (3, 4)
        ) x(id1, id2)
    )
    SELECT    t.*,   x.*
    FROM t
    CROSS JOIN LATERAL (SELECT t.id1) x(id3) -- referencing t.id1
    UNION ALL 
    SELECT    t.*,   x.*
    FROM t
    CROSS JOIN LATERAL (SELECT t.id2) x(id3);
    


    有趣的是,在这种情况下使用 SELECT 而不是 VALUES 会导致错误:

    WITH t AS (
    SELECT *
        FROM (VALUES
            (1, 2)
        ,   (3, 4)
        ) x(id1, id2)
    )
    SELECT    t.*,   x.*
    FROM t
    CROSS JOIN LATERAL (VALUES (t.id1), (t.id2)) x(id3)  
    -- regardless of single or more values
    

    SQL 执行内部错误:处理因错误而中止

    db<>fiddle demo

    UNION ALL模拟多行:

    WITH t AS (
    SELECT *
        FROM (VALUES
            (1, 2)
        ,   (3, 4)
        ) x(id1, id2)
    )
    SELECT    t.*,   x.*
    FROM t
    CROSS JOIN LATERAL (SELECT t.id1 UNION ALL SELECT t.id2) x(id3);
    

    SQL 编译错误:无法评估不受支持的子查询类型

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-10
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多