创建一个VIEW以根据最大日期从表中删除重复项



我有一个表,它每天都会附加数据并记录导入的日期,但它会附加重复的数据。

我的最终目标是根据导入列的最低日期删除重复项。

这将是该表的初始状态:

表客户端

2022年7月18日2022年7月18日2022年7月20日2022年7月20日
姓名 导入
Bob John 2022年7月18日
Marta 白色
Ryan 最大
Bob John 2022年7月20日
Marta 白色 2022年7月20日
Ryan 最大值
Brian 红色

正如我在评论中提到的,理想情况下,每个客户端都有一个唯一的标识符。缺少这些,我将使用name ||'_'||姓氏作为伪主键。

有几种方法可以在这里使用

第一种是使用子查询加入密钥和导入日期

CREATE VIEW CLIENTS_VIEW AS
SELECT C.* FROM CLIENTS C
JOIN
(
SELECT 
name||'_'||surname as client_name
, MAX(imported) as latest
FROM CLIENTS
GROUP BY 1
) MI ON MI.client_name = C.name||'_'||surname AND MI.latest = C.imported

另一种是根据另一个答案使用行号函数

CREATE VIEW CLIENTS_VIEW AS
SELECT C.* FROM CLIENTS C
QUALIFY row_number() over (partition by Name, surname order by imported desc)=1

根据我的经验,如果数据量是大的,那么子查询的性能更高

还有其他选择,例如使用NOT EXISTS、连接回同一个表或使用CTE

对于较大的表,性能最好的选择是为每个客户端创建另一个具有最新数据的表(同样需要一个唯一的标识符(,并定期使用MERGE来追加新数据。

像这样的

merge into clients_latest cl using (select * from clients) as c on 
cl.name||'_'||surname = c.name||'_'||surname
when matched then update set cl.imported = c.imported
when not matched then insert (name, surname, imported) values (c.name, 
c.surname, c.imported);

如果此数据不经常更改,则半定期计划任务可以为您运行此任务。如果表一直被追加,那么仅追加的表流可能是一个更快的选择,因为自上次追加以来,您只会追加新数据

您可以尝试的一种方法是使用分析函数

select * from (
select column1 as Name, column2 as Surname, column3 as Imported, row_number() over (partition by Name, surname order by imported desc) rnum from values
('Bob','John','18-07-2022'),
('Marta','White','18-07-2022'),
('Ryan','Max','18-07-2022'),  
('Bob','John','20-07-2022'),  
('Marta','White','20-07-2022'), 
('Ryan','Max','20-07-2022'),  
('Brian','Red','20-07-2022')
) where rnum = 1;

最新更新