SQL去重。有偿!12345678

部门表的部门数据由三个系统提供,三个系统提供的时候可能出现重复的部门(根据部门id判断),当出现重复部门数据的时候取第三个部门的提供的部门数据
where 条件是根据部门名称做查询



```sql
create table `t_org` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `org_code` varchar(20) NOT NULL COMMENT '部门编号',
  `org_name` varchar(20) NOT NULL COMMENT '部门名称',
  `org_source` int(1) NOT NULL COMMENT '系统类型:系统1,系统2,系统3',
  PRIMARY KEY (`id`)
)

select org_code,org_name,org_source from t_org
where
(case when
    (select if(count(org_code) > 1,ture,false) from t_org where org_name ='部门名称') 
then
    org_name ='部门名称' and org_source = 3
else
    org_name ='部门名称'
end)


```

写在前面:最好的方法当然是在insert的时候就只保留一条,如果要保留记录可以建副表,但主表只保留一条,当然有时船大难掉头,改起来牵扯大,这时就见仁见智吧。
回答题主的问题:
以mysql为例
CREATE TABLE data_1 (
id int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
dep_id int(11) DEFAULT NULL COMMENT '部门id',
dep_name varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '部门名称',
sjly varchar(10) COLLATE utf8_bin DEFAULT '' COMMENT '数据来源 system1:系统1,system2:系统2 system3:系统3',
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO data_1(id, dep_id, dep_name, sjly) VALUES (1, 1, '部门1', 'system1');
INSERT INTO data_1(id, dep_id, dep_name, sjly) VALUES (2, 2, '部门2', 'system2');
INSERT INTO data_1(id, dep_id, dep_name, sjly) VALUES (3, 3, '部门3', 'system3');
INSERT INTO data_1(id, dep_id, dep_name, sjly) VALUES (4, 3, '部门3', 'system2');
INSERT INTO data_1(id, dep_id, dep_name, sjly) VALUES (5, 4, '部门4', 'system3');
INSERT INTO data_1(id, dep_id, dep_name, sjly) VALUES (6, 4, '部门4', 'system1');

#每个dep_id只取一条,优先以系统3的数据为准
SELECT d1.* FROM data_1 d1
INNER JOIN (
SELECT dep_id,max(CASE sjly WHEN 'system3' THEN 3 WHEN 'system2' THEN 2 WHEN 'system1' THEN 1 END) as sjly FROM data_1 GROUP BY dep_id
) d2 ON d2.dep_id=d1.dep_id AND (CASE d1.sjly WHEN 'system3' THEN 3 WHEN 'system2' THEN 2 WHEN 'system1' THEN 1 END)=d2.sjly

简单的操作替换复杂的sql语句:对于第一个部门提供的数据,直接insert;对于第二个部门提供的数据,库中已存在的部门之间忽略/放弃,不存在的部门数据直接insert;对于第三个部门提供的数据,库中已存在的部门数据使用update更新,不存在的部门数据直接insert。

select * from 部门表
where 部门名称=部门名称
order by 时间 desc
group by 部门ID

三个系统的数据库是否在同一个服务器上,可以使用union join 每个系统union 额外增加一个字段标识第几个系统(1,2,3),然后union 之后进行group by 部门id ,系统标识 。select 部门id,max(系统标识) from tb group by 部门id

当然最好是代码逻辑进行处理。思路更加清晰一些

-- 说明
-- 部门表 department_table
-- 三个系统提供数据,假设来自系统1:system_1  系统2:system_2 系统3:system_3

-- 1.筛选重复部门数据,且重复数据包含于第三个部门
select dept_id,max(fromSystem) from
(
select dept_id ,'1' fromSystem from system_1 union all  -- 打标志位
select dept_id ,'2' fromSystem from system_2 union all
select dept_id ,'3' fromSystem from system_3
)t group by t.dept_id having count(0) > 1 and max(fromSystem) = 3;

-- 2.上面得到的 dept_id:  select * from system_3 a where a.dept_id = '上述查询到dept_id'
-- 即为重复的部门id数据(取第三个部门的)。至于第1、2部门数据重复的部门数据(没有系统3提供的部门),按照上述类似,保留哪条
-- 3.确定上述重复数据取值,其他数据 not in 上述重复的dept_id即可
-- 4.最后合并数据, 重复数据的最终取值 union all 不重复的数据

SELECT t.id,t.dept_name,t.type,t.create_time from (SELECT id,dept_name,type,create_time from depet
HAVING 0 order by type desc) t
where t.dept_name = "部门名称"
group by t.dept_name
order by t.id desc;

问题描述不是很清晰。是三个服务吗,还是三个库

自己改一下,目前t3优先级最高。



CREATE TABLE `test` (
  `dep_id` int(11),
  `dep_name` varchar(50),
  `sys_id` int(11)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into test(dep_id,dep_name,sys_id) values (1,'a1',1);
insert into test(dep_id,dep_name,sys_id) values (2,'b1',1);
insert into test(dep_id,dep_name,sys_id) values (3,'c1',1);
insert into test(dep_id,dep_name,sys_id) values (2,'b2',2);
insert into test(dep_id,dep_name,sys_id) values (2,'b3',3);

select
    t0.dep_id
    , CASE 
        WHEN t3.dep_id IS NOT NULL 
            THEN t3.dep_name 
        WHEN t1.dep_id IS NOT NULL 
            THEN t1.dep_name 
        WHEN t2.dep_id IS NOT NULL 
            THEN t2.dep_name 
        ELSE null 
        END AS dep_name
    , t1.dep_name as dep_name1
    , t2.dep_name as dep_name2
    , t3.dep_name as dep_name3 
from
    (select dep_id from test group by dep_id) t0 
    left outer join test t1 
        on t0.dep_id = t1.dep_id 
        and t1.sys_id = '1' 
    left outer join test t2 
        on t0.dep_id = t2.dep_id 
        and t2.sys_id = '2' 
    left outer join test t3 
        on t0.dep_id = t3.dep_id 
        and t3.sys_id = '3'
;

这是一个典型的开窗问题,很好解决。
mysql低版本示例如下:


select z.client_name,z.client_source,z.salesman,z.order_date,z.rank from(
select x.*,@rownum:=@rownum+1,if(@part=x.client_name,@r:=@r+1,@r:=1) as rank,@part:=x.client_name from (
select order_date,client_name,client_source,salesman from order_info e
order by e.client_name,e.order_date desc
) x,(select @rownum:=0,@part:=null,@r:=0) rt
)z where z.rank =1

mysql高版本示例如下:

select t.*
from (select *, row_number() over (partition by client_name,client_source,salesman order by order_date desc) rw from  order_info) t
where t.rw = 1

写个存储过程,利用游标循环insert,重复就跳过


DROP TABLE IF EXISTS `depet`;
 
CREATE TABLE `depet` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dept_name` varchar(20) DEFAULT '' COMMENT '部门名',
  `type` int(1) DEFAULT '1' COMMENT '系统类型:1系统1;2.系统2;3.系统3',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

创建表,允许系统同时录入相同的的数据

img


现在每个系统录入的时候都有相同存在的财务部,录入的时候只选取部门3的数据,部门名称不重复的显示到各部门

SELECT * FROM depet
WHERE
(CASE WHEN
    (SELECT IF(COUNT(1) > 1,TRUE,FALSE) FROM depet WHERE dept_name ='部门名称') 
THEN
    dept_name ='部门名称' AND TYPE=3
ELSE
    dept_name ='部门名称'
END)

img


这样重复部门就只显示第三个系统录入的信息了

没有真实数据不太好整,如果三个系统部门没有缺失,只是部门名称不同
你用left join

select distinct t3.dept_id , 
          IFNULL(t3.dept_name ,IFNULL(t2.dept_name ,t1.dept_name ))
  from system_3 t3 
left join system_2 t2 on t3.dept_id =t2.dept_id
left join system_1 t1 on t3.dept_id =t1.dept_id

如果是部门有缺失

--先创建一个临时表
create temporary table temp_table(
    dept_id int,
    dept_name varchar(50),
    type int
) ENGINE = InnoDB;
--数据插入临时表
insert into temp_table select dept_id ,dept_name,1 as type from system_1 union all
select dept_id ,dept_name,2 as type from system_2 union all
select dept_id ,dept_name,3 as type from system_3;
--去重
select dept_id ,dept_name from temp_table t1
inner join (select dept_id ,max(type) type from  temp_table group by dept_id ) t2 on t1.dept_id =t2.dept_id and t1.type=t2.type


select DISTINCT t.* from
(
select dept1.* from dept1 union all
select dept2.* from dept2 union all
select dept3.* from dept3
)t WHERE t.dept_name like concat( '%', #{deptName}, '%') ;

需要提供表结构,以及测试数据的,这样,大家都只是在猜,不知道真正应该如何去写的,你说的是部门由3个系统提供的,这3个系统是共用一个数据库一个表?
还是怎么说?看你说的部门重复好像是ID重复,不是名称重复,所以这个你得详细说明结构和测试数据的

select dept_id,max(fromSystem) from
(
select dept_id ,'1' fromSystem from system_1 union all  
select dept_id ,'2' fromSystem from system_2 union all
select dept_id ,'3' fromSystem from system_3
)t group by t.dept_id having count(0) > 1 and max(fromSystem) = 3;


用开窗函数分组,然后排序字段使用case when子句判断数据来源,partition by 部门名称 order by case when 数据来源=’system3' then 1 else 2 end

表一和表二加条件,not exists,例如:


select * from1 a where not exists (select * from 表三 c where c.部门id = a.部门id)
union all select * from2 a where not exists (select * from 表三 c where c.部门id = a.部门id)
union all select * from3

如果是已经将三个系统的部门数据,放到一个部门表里面了,现在需要去重吗,可以分步处理

1、根据部门id分组,并用having count(*) >1,选出有重复的部门id;

2、找到这些部门id中,包含系统3的部门id;

3、删除第二步id中,系统1和系统2的数据,保留系统3的数据;

4、第一步的id集合与第二步的id集合做差集,是有重复但是没有系统3提供的部门,需要用别的方式进行选择,保留哪一条

对部门进行group by就行了,重复的部门就会变成一个

https://download.csdn.net/download/weixin_38675777/13690747?spm=1005.2026.3001.5635&utm_medium=distribute.pc_relevant_ask_down.none-task-download-2~default~OPENSEARCH~Rate-4-13690747-ask-7756728.pc_feed_download_top3ask&depth_1-utm_source=distribute.pc_relevant_ask_down.none-task-download-2~default~OPENSEARCH~Rate-4-13690747-ask-7756728.pc_feed_download_top3ask

根据题主提供信息,模拟测试案例进行解决问题(已提供具体sql脚本,结合说明复制到本地更容易理解)。
1.创建部门表,每个部门需要关联三个系统(系统1、系统2、系统3)中的一个,支持录入相同的部门名。创建表结构如下:

DROP TABLE IF EXISTS `depet`;

CREATE TABLE `depet` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dept_name` varchar(20) DEFAULT '' COMMENT '部门名',
  `type` int(1) DEFAULT '1' COMMENT '系统类型:1系统1;2.系统2;3.系统3',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

2.添加测试数据

img


添加数据说明:

系统1中有财务部、市场部、销售部

img


系统2中有后勤部、财务部、技术部

img

系统3中有网络部、品牌部、财务部

img


三个系统中财务部数据重复
查询要求:根据部门名称查询部门信息,部门名称重复的仅现实第三个系统录入的部门信息,部门名称不重复的显示对应的部门信息。sql如下:

SELECT * FROM depet
WHERE
(CASE WHEN
    (SELECT IF(COUNT(1) > 1,TRUE,FALSE) FROM depet WHERE dept_name ='部门名称') 
THEN
    dept_name ='部门名称' AND TYPE=3
ELSE
    dept_name ='部门名称'
END)

3.按照部门名称查询部门信息
部门名称重复场景测试:
部门名称为财务部,应该查询出三条数据,但是要求默认显示系统3的财务部;

img

部门名称不重复场景测试:
部门名称为技术部,应该查询出一条。查询sql以及结果:

img

测试完成满足需求。
如有帮助,欢迎采纳!