【发布时间】:2020-01-26 16:58:26
【问题描述】:
我想将此 SQL 查询转换为 ANSI SQL。我无法理解这个查询的逻辑。
我使用雪花数据仓库,但由于加入前的“删除”语句,它不理解此查询,因此我试图将其分解。据我了解,行号列是根据时间戳为我提供从 1 到 N 的顺序并将其放置在 C 中。然后 C 在第一行以外的行(基于 id)上与自身连接并放置在 C1 中。然后从整体数据中删除C1,只留下第一行。
我可能对逻辑的理解有误,但我不习惯在加入之前看到“删除”语句。让我知道我的逻辑是否正确,或者指出我正确的方向。
此查询是从THISstackoverflow 问题复制/粘贴的,该问题与我要解决的确切情况相同,但规模更大。
with C as
(
select ID,
row_number() over(order by DT) as rn
from YourTable
)
delete C1
from C as C1
inner join C as C2
on C1.rn = C2.rn-1 and
C1.ID = C2.ID
我要解决的具体问题是这样的。假设我有这张桌子。我需要按主键组合(primKey 1 和 2)对行进行分区,同时保持时间戳顺序。
ID primKey1 primKey2 checkVar1 checkVar2 theTimestamp
100 1 2 302 423 2001-07-13
101 3 6 506 236 2005-10-25
100 1 2 302 423 2002-08-15
101 3 6 506 236 2008-12-05
101 3 6 300 100 2010-06-10
100 1 2 407 309 2005-09-05
100 1 2 302 423 2012-05-09
100 1 2 302 423 2003-07-24
一旦对行进行分区并且时间戳在每个分区中排序,我需要删除重复的 checkVar 组合(checkVar 1 & 2)行,直到下一次更改。因此给我留下了最早的唯一行。带星号的行是需要删除的行,因为它们是重复的。
ID primKey1 primKey2 checkVar1 checkVar2 theTimestamp
100 1 2 302 423 2001-07-13
*100 1 2 302 423 2002-08-15
*100 1 2 302 423 2003-07-24
100 1 2 407 309 2005-09-05
100 1 2 302 423 2012-05-09
101 3 6 506 236 2005-10-25
*101 3 6 506 236 2008-12-05
101 3 6 300 100 2010-06-10
这是最终结果。如您所见,对于 ID=100,即使第 1 条和第 3 条记录相同,但 checkVar 组合在两者之间发生了变化,这很好。我只删除重复项,直到值发生变化。
ID primKey1 primKey2 checkVar1 checkVar2 theTimestamp
100 1 2 302 423 2001-07-13
100 1 2 407 309 2005-09-05
100 1 2 302 423 2012-05-09
101 3 6 506 236 2005-10-25
101 3 6 300 100 2010-06-10
【问题讨论】:
-
请说明您要实现的逻辑。从查询中看不出来。
-
基于 CTE 的删除是适用于 Sql Server 但不适用于其他 DBMS 的事情之一。但是对于标准 SQL,可能需要一个在表中唯一的额外字段。显然,该 ID 不是该表中的主键,因为它有重复。
-
嘿戈登和 LukStorms。我编辑了问题以显示我要完成的工作。虽然在我的情况下,没有真正的主键概念,因为我使用的主键不是唯一的。它们主要用于分区目的。虽然,主键和时间戳的组合总是唯一的。
-
您是要从 CTE 还是从 YourTable 中删除?如果这是一次性的,您可能只想使用 CTAS 并创建一个新表。如果这是一个持续的事情,那么您可能想要在基表上创建一个物化视图。
标签: sql snowflake-cloud-data-platform