sql按条件分组

时间:2021-11-05 15:11:11
原数据 
if   object_id(N'tempdb..#tb')   is   not   null   
drop   table  #tb 
create table #tb([id] int, sex int , [Name] varchar(13),depart int,subdepart int,[group] int) 
insert #tb select 52001,0,'aaa',1,2,0 
union all select 52002,1,'bbb',1,2,0 
union all select 52003,0,'ccc',1,4  ,0  
union all select 52004,1,'ddd',1,6 ,0 
union all select 52005,0,'eee',2,1,0 
union all select 52006,1,'fff',6,23,0 
union all select 52007,0,'ggg',3,6  ,0 
union all select 52008,1,'hhh',2,1,0 
union all select 52009,0,'iii',3,6,0 
union all select 52010,1,'jjj',3,6   ,0 
union all select 52011,0,'kkk',1,34 ,0 
union all select 52012,1,'lll',1,5,0 
union all select 52013,0,'mmm',4,1,0 
union all select 52014,1,'nnn',4,3 ,0 
union all select 52015,0,'ooo',1,3,0 
select * from #tb 

要求的结果 


if   object_id(N'tempdb..#tc')   is   not   null   
drop   table  #tc 
create table #tc([id] int, sex int , [Name] varchar(13),depart int,subdepart int,[group] int) 
insert #tb select 52001,0,'aaa',1,2,1 
union all select 52002,1,'bbb',1,2,1 
union all select 52003,0,'ccc',1,4  ,2  
union all select 52004,1,'ddd',1,6 ,2 
union all select 52005,0,'eee',2,1,6 
union all select 52006,1,'fff',6,23,9 
union all select 52007,0,'ggg',3,6  ,7 
union all select 52008,1,'hhh',2,1,6 
union all select 52009,0,'iii',3,6,5 
union all select 52010,1,'jjj',3,6   ,5 
union all select 52011,0,'kkk',1,34 ,4 
union all select 52012,1,'lll',1,5,4 
union all select 52013,0,'mmm',4,1,8 
union all select 52014,1,'nnn',4,3 ,8 
union all select 52015,0,'ooo',1,3,3 

select * from #tc 
order by [group] 

`具体的规则就是,sex表示性别,要不同性别的两个人配对,两人一组,或一人一组, 
配对原则,首先必须 depart 一致 ,否则,不能配对。在 depart 一致的前提下,subdepart 如果一致,则配成一对,剩下subdepart 不一致的,depart 一致也能配对,参照结果,不知道我说明白没 

谢谢大家

8 个解决方案

#1


顶阿,在线等

#2


顶阿

#3


没看懂,这个配对是尽量按depart或subdepart靠在一起就配,还是尽量按id的顺序配
为什么ggg,iii,jjj中是iii,jjj配,而不是ggg,jjj配
group又是按什么顺序得出来的

#4


depart 必须一样,才能分成一组,如果subdepart 也一样的话,优先配对,只能两个或一个一组,条件一样的话,可以*组合,只取一种,group可以随便制定顺序,只要可以区分出不同的组来就可以,id也没有顺序限制
谢谢

#5


if   object_id(N'tempdb..#tb')   is   not   null     
drop   table  #tb   
create table #tb([id] int, sex int , [Name] varchar(13),depart int,subdepart int,[group] int)   
insert #tb select 52001,0,'aaa',1,2,0   
union all select 52002,1,'bbb',1,2,0   
union all select 52003,0,'ccc',1,4  ,0    
union all select 52004,1,'ddd',1,6 ,0   
union all select 52005,0,'eee',2,1,0   
union all select 52006,1,'fff',6,23,0   
union all select 52007,0,'ggg',3,6  ,0   
union all select 52008,1,'hhh',2,1,0   
union all select 52009,0,'iii',3,6,0   
union all select 52010,1,'jjj',3,6   ,0   
union all select 52011,0,'kkk',1,34 ,0   
union all select 52012,1,'lll',1,5,0   
union all select 52013,0,'mmm',4,1,0   
union all select 52014,1,'nnn',4,3 ,0   
union all select 52015,0,'ooo',1,3,0   

declare @Group int

declare @id1 int
declare @id2 int

set @Group=1

while exists (
select 1 from #tb a,#tb b
where a.sex<>b.sex
and a.depart=b.depart
and a.[group]=0
and b.[group]=0
and a.subdepart=b.subdepart
)
begin
    select top 1 @id1=a.id,@id2=b.id from #tb a,#tb b
    where a.sex<>b.sex
    and a.depart=b.depart
    and a.[group]=0
    and b.[group]=0
    and a.subdepart=b.subdepart
    
    update #tb set [group]=@Group
    where id in (@Id1,@id2)    

    set @Group=@Group+1
end

while exists (
select 1 from #tb a,#tb b
where a.sex<>b.sex
and a.depart=b.depart
and a.[group]=0
and b.[group]=0
)
begin
    select top 1 @id1=a.id,@id2=b.id from #tb a,#tb b
    where a.sex<>b.sex
    and a.depart=b.depart
    and a.[group]=0
    and b.[group]=0
    
    update #tb set [group]=@Group
    where id in (@Id1,@id2)    

    set @Group=@Group+1
end

while exists (
select 1 from #tb
where [group]=0
)
begin
    set rowcount 1    
    update #tb set [group]=@Group
    where [Group]=0
    set rowcount 0

    set @Group=@Group+1
end

select * from #tb
order by [group]

--结果
id          sex         Name          depart      subdepart   group       
----------- ----------- ------------- ----------- ----------- ----------- 
52001       0           aaa           1           2           1
52002       1           bbb           1           2           1
52005       0           eee           2           1           2
52008       1           hhh           2           1           2
52010       1           jjj           3           6           3
52007       0           ggg           3           6           3
52003       0           ccc           1           4           4
52004       1           ddd           1           6           4
52011       0           kkk           1           34          5
52012       1           lll           1           5           5
52013       0           mmm           4           1           6
52014       1           nnn           4           3           6
52006       1           fff           6           23          7
52009       0           iii           3           6           8
52015       0           ooo           1           3           9

(所影响的行数为 15 行)

#6




create table #tb([id] int, sex int , [Name] varchar(13),depart int,subdepart int,[group] int)  
insert #tb select 52001,0,'aaa',1,2,0  
union all select 52002,1,'bbb',1,2,0  
union all select 52003,0,'ccc',1,4  ,0   
union all select 52004,1,'ddd',1,6 ,0  
union all select 52005,0,'eee',2,1,0  
union all select 52006,1,'fff',6,23,0  
union all select 52007,0,'ggg',3,6  ,0  
union all select 52008,1,'hhh',2,1,0  
union all select 52009,0,'iii',3,6,0  
union all select 52010,1,'jjj',3,6   ,0  
union all select 52011,0,'kkk',1,34 ,0  
union all select 52012,1,'lll',1,5,0  
union all select 52013,0,'mmm',4,1,0  
union all select 52014,1,'nnn',4,3 ,0  
union all select 52015,0,'ooo',1,3,0  
go

declare @i int
set @i=0

update a 
set @i=@i+1,[group]=@i
from #tb a,#tb b
where a.sex=0 and b.sex=1 and a.[group]=0  and b.[group]=0 
and a.depart=b.depart and a.subdepart=b.subdepart 

update b set [group]=a.[group]
from #tb a,#tb b
where a.sex=0 and b.sex=1 and a.[group]>0  and b.[group]=0 
and a.depart=b.depart and a.subdepart=b.subdepart

update a set [group]=0
from #tb a
where [group]>0 and not exists(select 1 from #tb where [group]=a.[group] and id<>a.id)

--declare @i int
--set @i=4
declare @t int
set @t=@i

update a
set @i=@i+1,[group]=@i
from #tb a,#tb b
where a.sex=0 and b.sex=1 and a.[group]=0  and b.[group]=0 
and a.depart=b.depart

update b set [group]=a.[group]
from #tb a,#tb b
where a.sex=0 and b.sex=1 and a.[group]>@t  and b.[group]=0 
and a.depart=b.depart

update a set [group]=0
from #tb a
where [group]>0 and not exists(select 1 from #tb where [group]=a.[group] and id<>a.id)

--declare @i int
--set @i=9
update #tb
set @i=@i+1,[group]=@i
where [group]=0

select * from #tb order by [group]

drop table #tb

#7


我的方法不大对,5楼的是正确的,学习。。。

#8


学习了.

#1


顶阿,在线等

#2


顶阿

#3


没看懂,这个配对是尽量按depart或subdepart靠在一起就配,还是尽量按id的顺序配
为什么ggg,iii,jjj中是iii,jjj配,而不是ggg,jjj配
group又是按什么顺序得出来的

#4


depart 必须一样,才能分成一组,如果subdepart 也一样的话,优先配对,只能两个或一个一组,条件一样的话,可以*组合,只取一种,group可以随便制定顺序,只要可以区分出不同的组来就可以,id也没有顺序限制
谢谢

#5


if   object_id(N'tempdb..#tb')   is   not   null     
drop   table  #tb   
create table #tb([id] int, sex int , [Name] varchar(13),depart int,subdepart int,[group] int)   
insert #tb select 52001,0,'aaa',1,2,0   
union all select 52002,1,'bbb',1,2,0   
union all select 52003,0,'ccc',1,4  ,0    
union all select 52004,1,'ddd',1,6 ,0   
union all select 52005,0,'eee',2,1,0   
union all select 52006,1,'fff',6,23,0   
union all select 52007,0,'ggg',3,6  ,0   
union all select 52008,1,'hhh',2,1,0   
union all select 52009,0,'iii',3,6,0   
union all select 52010,1,'jjj',3,6   ,0   
union all select 52011,0,'kkk',1,34 ,0   
union all select 52012,1,'lll',1,5,0   
union all select 52013,0,'mmm',4,1,0   
union all select 52014,1,'nnn',4,3 ,0   
union all select 52015,0,'ooo',1,3,0   

declare @Group int

declare @id1 int
declare @id2 int

set @Group=1

while exists (
select 1 from #tb a,#tb b
where a.sex<>b.sex
and a.depart=b.depart
and a.[group]=0
and b.[group]=0
and a.subdepart=b.subdepart
)
begin
    select top 1 @id1=a.id,@id2=b.id from #tb a,#tb b
    where a.sex<>b.sex
    and a.depart=b.depart
    and a.[group]=0
    and b.[group]=0
    and a.subdepart=b.subdepart
    
    update #tb set [group]=@Group
    where id in (@Id1,@id2)    

    set @Group=@Group+1
end

while exists (
select 1 from #tb a,#tb b
where a.sex<>b.sex
and a.depart=b.depart
and a.[group]=0
and b.[group]=0
)
begin
    select top 1 @id1=a.id,@id2=b.id from #tb a,#tb b
    where a.sex<>b.sex
    and a.depart=b.depart
    and a.[group]=0
    and b.[group]=0
    
    update #tb set [group]=@Group
    where id in (@Id1,@id2)    

    set @Group=@Group+1
end

while exists (
select 1 from #tb
where [group]=0
)
begin
    set rowcount 1    
    update #tb set [group]=@Group
    where [Group]=0
    set rowcount 0

    set @Group=@Group+1
end

select * from #tb
order by [group]

--结果
id          sex         Name          depart      subdepart   group       
----------- ----------- ------------- ----------- ----------- ----------- 
52001       0           aaa           1           2           1
52002       1           bbb           1           2           1
52005       0           eee           2           1           2
52008       1           hhh           2           1           2
52010       1           jjj           3           6           3
52007       0           ggg           3           6           3
52003       0           ccc           1           4           4
52004       1           ddd           1           6           4
52011       0           kkk           1           34          5
52012       1           lll           1           5           5
52013       0           mmm           4           1           6
52014       1           nnn           4           3           6
52006       1           fff           6           23          7
52009       0           iii           3           6           8
52015       0           ooo           1           3           9

(所影响的行数为 15 行)

#6




create table #tb([id] int, sex int , [Name] varchar(13),depart int,subdepart int,[group] int)  
insert #tb select 52001,0,'aaa',1,2,0  
union all select 52002,1,'bbb',1,2,0  
union all select 52003,0,'ccc',1,4  ,0   
union all select 52004,1,'ddd',1,6 ,0  
union all select 52005,0,'eee',2,1,0  
union all select 52006,1,'fff',6,23,0  
union all select 52007,0,'ggg',3,6  ,0  
union all select 52008,1,'hhh',2,1,0  
union all select 52009,0,'iii',3,6,0  
union all select 52010,1,'jjj',3,6   ,0  
union all select 52011,0,'kkk',1,34 ,0  
union all select 52012,1,'lll',1,5,0  
union all select 52013,0,'mmm',4,1,0  
union all select 52014,1,'nnn',4,3 ,0  
union all select 52015,0,'ooo',1,3,0  
go

declare @i int
set @i=0

update a 
set @i=@i+1,[group]=@i
from #tb a,#tb b
where a.sex=0 and b.sex=1 and a.[group]=0  and b.[group]=0 
and a.depart=b.depart and a.subdepart=b.subdepart 

update b set [group]=a.[group]
from #tb a,#tb b
where a.sex=0 and b.sex=1 and a.[group]>0  and b.[group]=0 
and a.depart=b.depart and a.subdepart=b.subdepart

update a set [group]=0
from #tb a
where [group]>0 and not exists(select 1 from #tb where [group]=a.[group] and id<>a.id)

--declare @i int
--set @i=4
declare @t int
set @t=@i

update a
set @i=@i+1,[group]=@i
from #tb a,#tb b
where a.sex=0 and b.sex=1 and a.[group]=0  and b.[group]=0 
and a.depart=b.depart

update b set [group]=a.[group]
from #tb a,#tb b
where a.sex=0 and b.sex=1 and a.[group]>@t  and b.[group]=0 
and a.depart=b.depart

update a set [group]=0
from #tb a
where [group]>0 and not exists(select 1 from #tb where [group]=a.[group] and id<>a.id)

--declare @i int
--set @i=9
update #tb
set @i=@i+1,[group]=@i
where [group]=0

select * from #tb order by [group]

drop table #tb

#7


我的方法不大对,5楼的是正确的,学习。。。

#8


学习了.