我有一个表格,其中有一列数字,然后其他列包含其他数据。我创建了“floor10”列,其中这些数字的下限为 10 的倍数(例如 8 -> 0、17 -> 10 等)。我想做的是创建另一列,该列具有“floor10”的滞后并为每一行显示它。每个“floor10”的不同值没有固定的行数,因此我不确定如何在 AWS Athena 上的 SQL 中使用 LAG 来执行此操作。
例如,
数量 | 10楼 | 姓名 |
---|---|---|
2 | 0 | 詹姆斯 |
23 | 20 | 詹姆斯 |
28 | 20 | 詹姆斯 |
16 | 10 | 詹姆斯 |
38 | 30 | 詹姆斯 |
8 | 0 | 约翰 |
54 | 50 | 约翰 |
56 | 50 | 约翰 |
28 | 20 | 约翰 |
22 | 20 | 约翰 |
25 | 20 | 约翰 |
我想要类似的东西,
数量 | 10楼 | 姓名 | floor10_prev |
---|---|---|---|
2 | 0 | 詹姆斯 | |
16 | 10 | 詹姆斯 | 0 |
23 | 20 | 詹姆斯 | 10 |
28 | 20 | 詹姆斯 | 10 |
38 | 30 | 詹姆斯 | 20 |
8 | 0 | 约翰 | |
22 | 20 | 约翰 | 0 |
25 | 20 | 约翰 | 0 |
28 | 20 | 约翰 | 0 |
54 | 50 | 约翰 | 20 |
56 | 50 | 约翰 | 20 |
以下方法不起作用:
SELECT
Num,
floor10,
Name,
LAG(floor10) OVER (PARTITION BY Name, Num ORDER BY Name, Num) AS floor10_prev
FROM table
或者,我尝试使用不同的“floor10”和“Name”创建一个子查询,然后在加入主表之前对其使用滞后。虽然这得到了预期的结果,但这似乎效率不高,并且在更大的数据集上执行此操作需要很长时间才能完成。
您可以创建一个 cte 来枚举每个名称 (Name_id) 的行并重复 10 层值,然后将其自连接到 Name_id - 1。
-- S a m p l e D a t a :
Create Table tbl ( Num Int, floor10 Int, Name Varchar(32) );
Insert Into tbl
VALUES ( 2, 0, 'James' ),
( 16, 10, 'James' ),
( 23, 20, 'James' ),
( 28, 20, 'James' ),
( 38, 30, 'James' ),
( 56, 50, 'John' ),
( 8, 0, 'John' ),
( 22, 20, 'John' ),
( 25, 20, 'John' ),
( 28, 20, 'John' ),
( 54, 50, 'John' ),
( 56, 50, 'John' );
WITH
grid AS
( Select Name,
Case When LAG(Coalesce(Name, 'XxX')) Over( Order By Name, Num ) = Name
Then Sum(1) Over( Partition By Name
Order By Name, Num
Rows Between Unbounded Preceding And Current Row)
Else 1
End as Name_id,
--
Num, floor10,
Row_Number() Over(Partition By Name, floor10 Order By Name, Num) as rn
From tbl
)
-- M a i n S Q L :
Select g1.Num, g1.floor10, g1.Name,
Max( Case When g1.rn = 1 Then g2.floor10 End ) Over(Partition By g2.Name
Order By g2.Name, g2.Num
Rows Between Unbounded Preceding And Current Row) as prev_floor10
From grid g1
Left Join grid g2 ON(g2.Name = g1.Name And g2.Name_id = g1.Name_id - 1)
Order By g1.Name, g1.Name_id
/* R e s u l t :
Num floor10 Name prev_floor10
--- ------- ------ ------------
2 0 James null
16 10 James 0
23 20 James 10
28 20 James 10
38 30 James 20
8 0 John null
22 20 John 0
25 20 John 0
28 20 John 0
54 50 John 20
56 50 John 20 */