问题描述
基本上,我有 Table 事件,其数据类似于
我想要这样的结果
就像我应该有一个唯一的条目,其中代码、单位和类型为 ACTIVE 状态。 所以第 1、2、3、7、8 行对我来说是重复的,我需要在最大validity_until 的情况下保留 1 个条目。需要为需要删除的条目获取 EventId 以从其他表中删除链接对象。 我可以通过查询检索重复项
SELECT code,unit,type FROM event where status='ACTIVE' GROUP BY code,type having count(*) > 1 ;
但是如何根据 max(validity_until) 从这些重复记录中检索 event_id。 一旦我有像 aaa、ccc 这样的 Event_id 被删除并需要保留 hhh,我就可以删除第 11 行的事件 aaa 的历史记录。但我想保留第 7 行,这是 ggg 事件,它的历史记录完好无损,这是第 6 行。 并且需要从该事件表中删除标识符为Event_id的Solution表中对应的重复记录。
输入:
行号 | Event_Id | 代码 | 单位 | 类型 | validity_until | 状态 |
---|---|---|---|---|---|---|
1 | aaa | 111 | 1 | A | 12-JAN-21 12.01.01.625000 PM | 活跃 |
2 | bbb | 222 | 2 | B | 02-JAN-21 12.01.01.625000 PM | 活跃 |
3 | 抄送 | 111 | 1 | A | 15-JAN-21 12.01.01.625000 PM | 活跃 |
4 | ddd | 333 | 2 | C | 12-JAN-21 12.01.01.625000 PM | 活跃 |
5 | ee | 222 | 3 | A | 11-JAN-21 12.01.01.625000 PM | 活跃 |
6 | ggg | 222 | 2 | B | 05-JAN-21 12.01.01.625000 PM | 无效 |
7 | ggg | 222 | 2 | B | 12-JAN-21 12.01.01.625000 PM | 活跃 |
8 | 呵呵 | 111 | 1 | A | 20-JAN-21 12.01.01.625000 PM | 活跃 |
9 | ddd | 333 | 2 | C | 10-JAN-21 12.01.01.625000 PM | 无效 |
10 | ee | 222 | 3 | A | 01-JAN-21 12.01.01.625000 PM | 无效 |
11 | aaa | 111 | 1 | A | 13-JAN-21 12.01.01.625000 PM | 无效 |
预期结果:
行号 | Event_Id | 代码 | 单位 | 类型 | validity_until | 状态 |
---|---|---|---|---|---|---|
4 | ddd | 333 | 2 | C | 12-JAN-21 12.01.01.625000 PM | 活跃 |
5 | ee | 222 | 3 | A | 11-JAN-21 12.01.01.625000 PM | 活跃 |
6 | ggg | 222 | 2 | B | 05-JAN-21 12.01.01.625000 PM | 无效 |
7 | ggg | 222 | 2 | B | 12-JAN-21 12.01.01.625000 PM | 活跃 |
8 | 呵呵 | 111 | 1 | A | 20-JAN-21 12.01.01.625000 PM | 活跃 |
9 | ddd | 333 | 2 | C | 10-JAN-21 12.01.01.625000 PM | 无效 |
10 | ee | 222 | 3 | A | 01-JAN-21 12.01.01.625000 PM | 无效 |
解决方法
使用 row_number
如下:
Select * from
(Select t.*,Row_number() over (partition by Code,Unit,type order by validity_until desc) as rn
From t) t
Where rn = 1 or status <> 'ACTIVE'
,
感谢分享样本数据和输出结果。这是您想要的查询:
WITH RESULTS AS (
SELECT ROW_NUMBER()OVER( PARTITION BY CODE,UNIT,TYPE ORDER BY validity_until DESC) AS RN,row_id,event_id,code,unit,type,validity_until,Status FROM event
)
SELECT * FROM RESULTS WHERE RN=1 OR STATUS='INACTIVE'
如果相同的代码、单位、类型和validity_until不可能有多个行,您可以使用dense_rank()而不是row_number。虽然两者都在某处使用分区,但我读到它更快(不确定,但您可以尝试一下):
WITH RESULTS AS (
SELECT dense_rank()OVER( PARTITION BY CODE,Status FROM event
)
SELECT * FROM RESULTS WHERE RN=1 OR STATUS='INACTIVE';