Greenplum/PostgreSQL中数据表数据去重的几种方法

GP主要用于数据仓库领域,在GP数据库中,如果由于ETL重复跑数导致数据重复的话,就需要进行去重复操作。

一种方法是把某一时间段的数据全部删掉,然后重新跑数据,这样其实工作量也比较大,需要补数据,重跑ETL。

另一种方法就是把重复的数据删掉就行,本文就是针对Greenplum分布式数据库如何进行去重复删除操作。

对于在PostgreSQL中,唯一确定一行的位置的是用ctid,可以用这个ctid作为一行的唯一标识;在Oracle中,数据表中的一行的唯一标识可以使用ROWID进行标识,这作为这一行的物理地址信息。而在GP中,要唯一的标识出一行表数据,需要使用gp_segment_id加上ctid进行标识。 gp_segment_id代表的是GP的segment的节点标识,每个子库的标识是唯一的。

因此删除重复数据的语句可以这么写:

delete from public.ods_m_automonitor_monitor_hour where gp_segment_id::varchar(100)||ctid::varchar(100) in
(select t.ctid from
(select gp_segment_id::varchar(100)||ctid::varchar(100) as ctid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_automonitor_monitor_hour ) t
where t.rows_num >=2);

这种语句适合所有的GP表,特别对那种没有唯一主键的数据仓库的表进行去重很有用。

先分析下,第一步:

select gp_segment_id::varchar(100)||ctid::varchar(100) as ctid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_automonitor_monitor_hour

查出来public.ods_m_automonitor_monitor_hour表中字段

gp_segment_id::varchar(100)||ctid::varchar(100) as ctid,mn_code,pollute_code,monitor_time

其中mn_code,pollute_code,monitor_time这几个字段是这个表中能够保证唯一性的字段,也就是这几个字段的值的任一某个组合在这张表只能出现一次,只要出现2次以上,就说明

数据重复了。

然后通过row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num对这几个字段进行分组排序

通过在外层对这个排序字段rows_num进行条件判断 :where t.rows_num >=2,就能过滤出重复的表数据。

然后再通过外部条件进行筛选,获取出这部分重复数据的行数据唯一标识:

delete from public.ods_m_automonitor_monitor_hour where gp_segment_id::varchar(100)||ctid::varchar(100) in 
(select t.ctid from ……)就可以去重重复。

另外,如果表中有唯一标识行的pkid,也就是说有主键ID的话,那直接用PKID作为去重字段:

delete from public.ods_m_automonitor_monitor_hour where pkid in
(select pkid from
(select pkid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_automonitor_monitor_hour ) t
where t.rows_num >=2);

postgresql中去重:

delete from public.ods_m_automonitor_monitor_hour where ctid in
(select ctid from
(select ctid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_automonitor_monitor_hour ) t
where t.rows_num >=2);

另外:

oracle中去重:

delete from public.ods_m_automonitor_monitor_hour where ROWID in
(select ROWID from
(select ROWID,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_automonitor_monitor_hour ) t
where t.rows_num >=2);

原文地址:https://www.cnblogs.com/nanshanjushi/p/11335286.html

时间: 2024-08-28 22:52:02

Greenplum/PostgreSQL中数据表数据去重的几种方法的相关文章

清空SQL Server数据库中所有表数据的方法

其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入死循环,二是这里使用了微软未正式公开的sp_MSForEachTable存储过程. 也许很多读者朋友都经历过这样的事情:要在开发数据库基础上清理一个空库,但由于对数据库结构缺乏整体了解,在删除一个表的记录时,删除不了,因为可能有外键约束,一个常见的数据库结构是一个主表,一个子表,这种情况下一般都得先删除子表记录,再删除主表记录. 说道删除数据记录,

Greenplum数据库中系统表pg_class详解

Greenplum数据库中系统表pg_class详解 pg_ class 可以说是数据字典最重要的-一个表了,它保存着所有表.视图.序列.索引的原数据信息,每一个DDL/DML操作都必须跟这个表发生联系, 其表结构详情,如下图: 原文地址:https://www.cnblogs.com/lizm166/p/12102500.html

Greenplum数据库中系统表gp_ distribution_ policy详解

Greenplum数据库中系统表gp_ distribution_ policy详解 gp_ distribution_ policy 表的分布键保存在gp_ distribution. policy 表中, 其表结构如下图: 原文地址:https://www.cnblogs.com/lizm166/p/12102518.html

将Excel数据导入mysql数据库的几种方法

将Excel数据导入mysql数据库的几种方法 “我的面试感悟”有奖征文大赛结果揭晓! 前几天需要将Excel表格中的数据导入到mysql数据库中,在网上查了半天,研究了半天,总结出以下几种方法,下面和大家分享一下: 一.用java来将Excel表格中的数据转到mysql中 这是我们用的第一种方法,就是在java找你感谢个类,然后这个类会将Excel表格中的数据存储到内存里,然后再从内存中读出来插入到数据库中,但是要 注意了,这里是存储到String[ ]数组里面,所以取出来的数据也是Strin

用easyui从servlet传递json数据到前端页面的两种方法

用easyui从servlet传递json数据到前端页面的两种方法 两种方法获取的数据在servlet层传递的方法相同,下面为Servlet中代码,以查询表中所有信息为例. //重写doGet方法 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stu

js中数组去重的几种方法

js中数组去重的几种方法         1.遍历数组,一一比较,比较到相同的就删除后面的                 function unique(arr){                         for(var i=0;i<arr.length;i++){                                 for(var j=i+1;j<arr.length;j++){                                         if(ar

Struts2中Action取得表单数据的几种方法

Struts2中Action取得表单数据的几种方法 Struts2中Action获得表单数据的几种方法struts2 Action获取表单传值 1.通过属性驱动式JSP: <form action="sys/login.action" method="post"> <input type="text" name="username"> <input type="submit"

问题-[Access]“无法打开工作组信息文件中的表 &#39;MSysAccounts&#39;”的问题的解决方法

问题现象:ado.net oledb方式访问Access数据库文件时报错“无法打开工作组信息文件中的表 'MSysAccounts'”的问题的解决方法 问题处理:1.数据库名称不能命名为:System.mdb可以改为其它名称如:user.mdb 2.表字段名称不能为id名称,可以改为其它名称:abcid,sdeid,dbid,... 3.表名,或字段名不能命名与Access数据库中系统名称相同可以改为其它名称 问题-[Access]"无法打开工作组信息文件中的表 'MSysAccounts'&q

PHP中获取文件扩展名的N种方法

PHP中获取文件扩展名的N种方法 从网上收罗的,基本上就以下这几种方式: 第1种方法: function get_extension($file) { substr(strrchr($file, '.'), 1); } 第2种方法: function get_extension($file) { return substr($file, strrpos($file, '.')+1); } 第3种方法: function get_extension($file) { return end(expl

在JS方法中返回多个值的三种方法

在使用JS编程中,有时需要在一个方法返回两个个或两个以上的数据,用下面的几种方法都可以实现: 1 使用数组的方式,如下: <html> <head> <title>JS函数返回多个值--oec2003</title> </head> <body> <input type="button" onclick="getNames()" value="test" /> &