迁移 SQL 服务器外部应用查询到 Snowflake 查询

Migrating SQL Server Outer Apply Query to Snowflake query

正在从 SQL 服务器迁移到 Snowflake。卡在下面的查询。在 Snowflake 中找不到任何等效项。 对于外部查询中的每一行,我们进入内部查询以获取小于外部查询中的日期键的顶级日期键。


    select a.datekey , a.userid, a.transactionid
    ,cast( cast(b.datekey as varchar(8)) as date) priorone
    from tableA a
    outer apply (select top 1 b.datekey
                  from tableA b where a.userid = b.userid
                  and b.transactionid < a.transactionid and b.datekey < a.datekey
    order by b.transactionid desc) as b

尝试了以下建议的答案:

create or replace table tableA
   (datekey date , userid int ,transactionid int)
   insert into tableA
   values('2020-06-01',1,101),('2020-06-02',1,102),('2020-06-02',1,103),('2020-06-01',2,104),('2020-06-02',2,105)
    select 
    a.datekey, 
    a.userid, 
    a.transactionid
    ,(
        select b.datekey
        from tableA b 
        where 
            a.userid = b.userid
            and b.transactionid < a.transactionid 
            and b.datekey < a.datekey
        order by b.transactionid desc
        limit 1
    ) priorone
from tableA a

您只能从外连接中获取一列,因此您可以将代码改写为直接相关子查询。

Snowflake 不支持 top,但它具有与 limit 相同的功能。

最后,你似乎想移除datekey的时间药水:你可以使用date()

select 
    a.datekey, 
    a.userid, 
    a.transactionid
    (
        select date(b.datekey)
        from tableA b 
        where 
            a.userid = b.userid
            and b.transactionid < a.transactionid 
            and b.datekey < a.datekey
        order by b.transactionid desc
        limit 1
    ) priorone
from tableA a

我认为您正在寻找的是 Snowflake 中的 LEAD() 函数。它将为您节省子查询或完全加入:

select 
    datekey, 
    userid, 
    transactionid,
    lead(datekey) over (partition by userid order by datekey desc) as priorone
from tableA;

这会根据日期键的降序获取用户 ID 的下一条记录。

您也可以使用 LAG() 并以相反的方式进行排序:

select 
    datekey, 
    userid, 
    transactionid,
    lag(datekey) over (partition by userid order by datekey asc) as priorone
from tableA;

lead/lag 不能替代 slq server outer apply

outer apply 让你做一个前 1,这是我用过它的唯一原因 - 超级方便。你不能在 CTE 中做 top 1,因为 CTE 在加入之前先被评估。因此,外部应用是我能看到的唯一解决方案。可惜没有雪花