【问题标题】:Migrating SQL Server Outer Apply Query to Snowflake query将 SQL Server 外部应用查询迁移到雪花查询
【发布时间】:2020-06-09 21:57:13
【问题描述】:

正在从 SQL Server 迁移到 Snowflake。卡在下面的查询中。在雪花中找不到任何等效的东西。 对于外部查询中的每一行,我们进入内部查询以获取比外部查询中的 datekey 小的顶部 datekey。


    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

【问题讨论】:

    标签: sql date sql-order-by snowflake-cloud-data-platform sql-limit


    【解决方案1】:

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

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

    这会根据 datekey 的降序获取 userid 的下一条记录。

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

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

    【讨论】:

      【解决方案2】:

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

      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 允许这种类型的子查询。低于错误SQL compilation error: Unsupported subquery type cannot be evaluated
      • @user1579411 - @GMB 的查询在简单的创建模式 create table tableA (datekey date, userid integer, transactionid integer) 上编译和运行。由于实际架构/查询不同,您可能会收到错误 - 可能更新您的帖子以添加更多细节?
      • 我尝试了简单的模式,但它仍然对我不起作用。得到相同的子查询错误。最近开始在 Snowflake 中工作并查看文档,它看起来并不支持共同相关的子查询。添加了有问题的简单架构和测试查询。
      • Snowflake 现在支持 TOP。
      【解决方案3】:

      lead/lag 不能替代 slq server external apply

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

      【讨论】:

        猜你喜欢
        • 2022-07-07
        • 1970-01-01
        • 1970-01-01
        • 2013-10-02
        • 2022-01-04
        • 1970-01-01
        • 2020-03-13
        • 1970-01-01
        • 2015-10-28
        相关资源
        最近更新 更多