迁移 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 在加入之前先被评估。因此,外部应用是我能看到的唯一解决方案。可惜没有雪花
正在从 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 在加入之前先被评估。因此,外部应用是我能看到的唯一解决方案。可惜没有雪花