部门表的部门数据由三个系统提供,三个系统提供的时候可能出现重复的部门(根据部门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;
创建表,允许系统同时录入相同的的数据
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)
没有真实数据不太好整,如果三个系统部门没有缺失,只是部门名称不同
你用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 * from 表1 a where not exists (select * from 表三 c where c.部门id = a.部门id)
union all select * from 表2 a where not exists (select * from 表三 c where c.部门id = a.部门id)
union all select * from 表3
如果是已经将三个系统的部门数据,放到一个部门表里面了,现在需要去重吗,可以分步处理
1、根据部门id分组,并用having count(*) >1,选出有重复的部门id;
2、找到这些部门id中,包含系统3的部门id;
3、删除第二步id中,系统1和系统2的数据,保留系统3的数据;
4、第一步的id集合与第二步的id集合做差集,是有重复但是没有系统3提供的部门,需要用别的方式进行选择,保留哪一条
对部门进行group by就行了,重复的部门就会变成一个
根据题主提供信息,模拟测试案例进行解决问题(已提供具体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.添加测试数据
系统1中有财务部、市场部、销售部
系统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)
3.按照部门名称查询部门信息
部门名称重复场景测试:
部门名称为财务部,应该查询出三条数据,但是要求默认显示系统3的财务部;
部门名称不重复场景测试:
部门名称为技术部,应该查询出一条。查询sql以及结果:
测试完成满足需求。
如有帮助,欢迎采纳!