我有一个表,它每天都会附加数据并记录导入的日期,但它会附加重复的数据。
我的最终目标是根据导入列的最低日期删除重复项。
这将是该表的初始状态:
表客户端
姓名 | 导入 | |
---|---|---|
Bob | John | 2022年7月18日 |
Marta | 白色 | 2022年7月18日|
Ryan | 最大 | 2022年7月18日|
Bob | John | 2022年7月20日 |
Marta | 白色 | 2022年7月20日 |
Ryan | 最大值 | 2022年7月20日|
Brian | 红色 | 2022年7月20日
正如我在评论中提到的,理想情况下,每个客户端都有一个唯一的标识符。缺少这些,我将使用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;