【发布时间】:2021-04-20 08:01:17
【问题描述】:
我正在尝试在不使用 LAG() 的情况下重新创建 LAG() 函数,但有一个依赖于列的动态 Offset。我要把这段代码复制到SparkSQL。
这是我的示例数据:
if object_id('tempdb.dbo.#myTable') is not null drop table #myTable
create table #myTable (id int,dates int, flag char, FromToFlagType varchar(2),FromToCounter INT)
insert into #myTable values(1, '20181031','V','VV',1)
insert into #myTable values(2, '20181130','V','VV',2)
insert into #myTable values(3, '20181231','V','VV',3)
insert into #myTable values(4, '20190131','F','VF',1)
insert into #myTable values(5, '20190228','F','FF',2)
insert into #myTable values(6, '20190331','F','FF',3)
insert into #myTable values(7, '20190430','F','FF',4)
insert into #myTable values(8, '20190531','V','FV',1)
insert into #myTable values(9, '20190630','V','VV',2)
insert into #myTable values(10, '20190731','V','VV',3)
id dates flag FromToFlagType FromToCounter
1 20181031 V VV 1
2 20181130 V VV 2
3 20181231 V VV 3
4 20190131 F VF 1
5 20190228 F FF 2
6 20190331 F FF 3
7 20190430 F FF 4
8 20190531 V VF 1
9 20190630 V VV 2
10 20190731 V VV 3
所以我想做的是复制以下结果,但不使用动态Offset:
select
*
,LAG(FromToFlagType,FromToCounter-1) OVER ( ORDER BY dates) AS FromToStage
from
#mytable
id dates flag FromToFlagType FromToCounter FromToStage
1 20181031 V VV 1 VV
2 20181130 V VV 2 VV
3 20181231 V VV 3 VV
4 20190131 F VF 1 VF
5 20190228 F FF 2 VF
6 20190331 F FF 3 VF
7 20190430 F FF 4 VF
8 20190531 V FV 1 FV
9 20190630 V VV 2 FV
10 20190731 V VV 3 FV
我知道您可以使用CTE 和JOIN 复制LAG(),但它似乎只有在您提前知道偏移量的情况下才有效。我在这里尝试过类似的方法,但我无法获得相同的结果。
我发现了类似的here,但我是 Spark 的新手,我需要一个使用 SparkSQL 的解决方案。我想如果我可以复制这个功能,我可以将它复制到“Spark”。
WITH FromToStage AS(
select
*
,id-(FromToCounter-1) AS id_2
from #mytable
--order by dates
)
SELECT
a.*
,b.FromToFlagType as FromToStage
FROM
FromToStage a
JOIN
FromToStage b
ON
a.id = b.id_2
order by dates
【问题讨论】:
-
为什么要重新发明轮子?
LAG允许 offset 在其表达式中包含列。 db<>fiddle. -
如果您必须重新发明轮子,请在 CTE 和自联接中使用
ROW_NUMBER;但它的性能会差很多。 -
SparkSQL 不允许动态偏移,它需要是文字。 spark.apache.org/docs/2.3.1/api/sql/index.html我尝试了自我加入,只要我提前知道我的偏移量,它似乎就可以工作。
-
那么,如果您的目标 DBMS 是 SQL Server 实例,为什么不使用存储过程呢?在 T-SQL 中,
LAGalways 支持将列作为 offset 定义的一部分。 -
我很困惑...你是想在 Spark 或 SQL Server 中做吗?
标签: sql tsql apache-spark-sql