合并多条记录为一条

时间:2021-05-15 00:27:15
由于操作问题产生了一些冗余记录。比如
ID     姓名     电话     地址
1001   李三     NULL     NULL
1008   李三     6639405  东石路
1413   李三     NULL     东石路29号
----------------------
我想要的结果:
合并 且修改第一条为 1001  李三  6639405  东石路29号
删除后面几条。
即:“电话”“地址”字段,哪个不为空用哪个,哪个详细(长度最长)用哪个。结果更新到第一条。
各位大侠,有没有办法?

PS:这个合并操作需要在WEB后台进行,因为同名不一定是同一人,所以要用WEB页面人为判断一下。

我是想看看有没有只用SQL语句就能解决的办法。实在不行,我这几条都读出来,再合并,再UPDATE。

8 个解决方案

#1


情况比较复杂
先把全不为空的查出来放到其他表里,
这个表还是删了吧。。。

#2


select id,max(姓名) as 姓名,max(地址) as 地址,max(邮编) as 邮编
 from tableA
 group by id

#3


合并多条记录为一条
引用 2 楼 superpander 的回复:
SQL code
select id,max(姓名) as 姓名,max(地址) as 地址,max(邮编) as 邮编
 from tableA
 group by id

#4


这样没办法标示哪个李三是你要合并的李三。
1001       李三           NULL           NULL 
1008       李三           6639405     东石路 
1413       李三           NULL           东石路29号
可能1413的李三和前面两个李三不是同一个人啊!这样就要求很智能了。对吧?

#5


引用楼主 shunruo 的回复:
因为同名不一定是同一人


那以什么分组来判断?

#6


用max是不对的,因为楼主的要求是长度最大,如果以名字分组可以这样

select 
  distinct
  姓名,
  电话=(select top 1 电话 from tb where 姓名=t.姓名 order by len(isnull(电话,'')) desc),
  地址=(select top 1 地址 from tb where 姓名=t.姓名 order by len(isnull(地址,'')) desc)
from tb t

#7



--> 测试数据: [tb]
if object_id('[tb]') is not null drop table [tb]
create table [tb] (ID int,姓名 varchar(4),电话 int,地址 varchar(10))
insert into [tb]
select 1001,'李三',null,null union all
select 1008,'李三',6639405,'东石路' union all
select 1413,'李三',null,'东石路29号'
go
--先修改
update tb set 电话=(select top 1 电话 from tb where 姓名=a.姓名 order by len(电话) desc),
地址=(select top 1 地址 from tb where 姓名=a.姓名 order by len(地址) desc)
from tb a
where not exists(select 1 from tb where 姓名=a.姓名 and id<a.id)
--删除多余的
delete tb from tb a where exists(select 1 from tb where 姓名=a.姓名 and id<a.id)

--查看结果:
select * from [tb]

-结果:

ID          姓名   电话          地址
----------- ---- ----------- ----------
1001        李三   6639405     东石路29号


#8


谢谢各位大牛们,谢谢楼上。 。我能否简化一下。我多次合并
每一次合并两个:
Merge(1001, 1008);
Merge(1001, 1413);

FUNC Merge(toId, fromId){....} 
// 以上这些为后台伪代码
---------------------------------------------
把 1008 合并到 1001要怎么弄?还是上面那个规则:保留尽可以全的数据。

--> 测试数据: [tb] 
if object_id('[tb]') is not null drop table [tb] 
create table [tb] (ID int,姓名 varchar(4),电话 int,地址 varchar(10))
insert into [tb] 
select 1001,'李三',null,null union all 
select 1008,'李三',6639405,'东石路' 
go 

--先修改 
update tb set 电话=(select top 1 电话 from tb where ID in (1001, 1008) order by len(电话) desc), 
地址=(select top 1 地址 from tb where  ID in (1001, 1008) order by len(地址) desc)
from tb a 
where ID=1001 
--删除多余的 
delete tb from tb a where ID=1008
--查看结果: 
select * from [tb] 
--结果: 

 ID       姓名   电话       地址 
----------- ---- ----------- ---------- 
 1001     李三  6639405   东石路

我把楼上的改了下,各位老师们,还能优化不?

#1


情况比较复杂
先把全不为空的查出来放到其他表里,
这个表还是删了吧。。。

#2


select id,max(姓名) as 姓名,max(地址) as 地址,max(邮编) as 邮编
 from tableA
 group by id

#3


合并多条记录为一条
引用 2 楼 superpander 的回复:
SQL code
select id,max(姓名) as 姓名,max(地址) as 地址,max(邮编) as 邮编
 from tableA
 group by id

#4


这样没办法标示哪个李三是你要合并的李三。
1001       李三           NULL           NULL 
1008       李三           6639405     东石路 
1413       李三           NULL           东石路29号
可能1413的李三和前面两个李三不是同一个人啊!这样就要求很智能了。对吧?

#5


引用楼主 shunruo 的回复:
因为同名不一定是同一人


那以什么分组来判断?

#6


用max是不对的,因为楼主的要求是长度最大,如果以名字分组可以这样

select 
  distinct
  姓名,
  电话=(select top 1 电话 from tb where 姓名=t.姓名 order by len(isnull(电话,'')) desc),
  地址=(select top 1 地址 from tb where 姓名=t.姓名 order by len(isnull(地址,'')) desc)
from tb t

#7



--> 测试数据: [tb]
if object_id('[tb]') is not null drop table [tb]
create table [tb] (ID int,姓名 varchar(4),电话 int,地址 varchar(10))
insert into [tb]
select 1001,'李三',null,null union all
select 1008,'李三',6639405,'东石路' union all
select 1413,'李三',null,'东石路29号'
go
--先修改
update tb set 电话=(select top 1 电话 from tb where 姓名=a.姓名 order by len(电话) desc),
地址=(select top 1 地址 from tb where 姓名=a.姓名 order by len(地址) desc)
from tb a
where not exists(select 1 from tb where 姓名=a.姓名 and id<a.id)
--删除多余的
delete tb from tb a where exists(select 1 from tb where 姓名=a.姓名 and id<a.id)

--查看结果:
select * from [tb]

-结果:

ID          姓名   电话          地址
----------- ---- ----------- ----------
1001        李三   6639405     东石路29号


#8


谢谢各位大牛们,谢谢楼上。 。我能否简化一下。我多次合并
每一次合并两个:
Merge(1001, 1008);
Merge(1001, 1413);

FUNC Merge(toId, fromId){....} 
// 以上这些为后台伪代码
---------------------------------------------
把 1008 合并到 1001要怎么弄?还是上面那个规则:保留尽可以全的数据。

--> 测试数据: [tb] 
if object_id('[tb]') is not null drop table [tb] 
create table [tb] (ID int,姓名 varchar(4),电话 int,地址 varchar(10))
insert into [tb] 
select 1001,'李三',null,null union all 
select 1008,'李三',6639405,'东石路' 
go 

--先修改 
update tb set 电话=(select top 1 电话 from tb where ID in (1001, 1008) order by len(电话) desc), 
地址=(select top 1 地址 from tb where  ID in (1001, 1008) order by len(地址) desc)
from tb a 
where ID=1001 
--删除多余的 
delete tb from tb a where ID=1008
--查看结果: 
select * from [tb] 
--结果: 

 ID       姓名   电话       地址 
----------- ---- ----------- ---------- 
 1001     李三  6639405   东石路

我把楼上的改了下,各位老师们,还能优化不?