ROW_NUMBER()按条件覆盖组



假设我们有一个列为";事件":

events
A
b
c
d
e
A
b
c
d
A
f

我想在这样的拆分上获得WindowGroups或只是一个带有row_number((的新列

events
A
b
c
d
e
f
g
----- split here ---
A
b
c
d
----- split here ---
A
f

所以我想把所有的行都放在";A";在";事件";列添加到一个组中。怎么做?我觉得这可以用Window函数来完成。

最后,我自己得到了一个解决方案。这是:

import org.apache.spark.sql.expressions.Window
val windowIndex = Window.partitionBy().orderBy("time")
val result = eventWithTime
.withColumn("groupId",
when($"events" === "A", row_number over windowIndex).otherwise(null))
.withColumn("groupId", last("groupId", ignoreNulls = true) over windowIndex)
.filter($"groupId".isNotNull)

(我使用"时间"列只是为了像示例中那样对事件进行排序(

这里的想法是找到所有";事件";用";A";并用唯一的id标记它们。我使用CCD_ 1和CCD_。(也许使用monotonically_increasing_id会更好,但我有很多数据,并且对monotonically_increasing_id的正确工作有一些假设(。之后,我使用了具有相同窗口的函数last。这里重要的是将ignoreNulls设置为";真";。这样,所有的null都将在当前行之前用第一个非null值填充。然后我只是把第一行放在第一行之前;A";因为它们仍然是null。

示例:

  1. 在进行任何操作之前
events
A
b
c
d
e
A
b
c
d
A
f
  1. 将唯一id分配给所有"A";s(否则为空(
events | groupId
A      | 1
b      | null
c      | null
d      | null
e      | null
A      | 2
b      | null
c      | null
d      | null
A      | 3
f      | null
  1. 使用最后一个非null值填充null
events | groupId
A      | 1
b      | 1
c      | 1
d      | 1
e      | 1
A      | 2
b      | 2
c      | 2
d      | 2
A      | 3
f      | 3

现在,我们可以通过groupId只使用groupBypartitionBy,并执行我们想要的操作。

CREATE TABLE  #tbl(event nvarchar(5))
insert into #tbl (event)values('A'),('b'),('c'),('d'),('e'),('A'),('b'),('c'), 
('d'),('A'),('f')    
CREATE TABLE #EventDetails(event nvarchar(5),groupId int)    
DECLARE @event_name varchar(20),@group_id int=0    

DECLARE event_cursor CURSOR FOR     
SELECT event
FROM #tbl     

OPEN event_cursor      
FETCH NEXT FROM event_cursor     
INTO @event_name    


WHILE @@FETCH_STATUS = 0    
BEGIN    
if(@event_name ='a')
begin
set @group_id  = @group_id+1        
insert into #EventDetails (event ,groupId)  
values (@event_name,@group_id)
end
else
begin
insert into #EventDetails (event ,groupId)  
values (@event_name,@group_id)
end


FETCH NEXT FROM event_cursor     
INTO @event_name      
END     
CLOSE event_cursor;    
DEALLOCATE event_cursor;    

select * from #EventDetails
drop table #EventDetails
drop table #tbl
=====================
Result
=====================
event   groupId
A         1
b         1
c         1
d         1
e         1
A         2
b         2
c         2
d         2
A         3
f         3

最新更新