Sql server Kari,我更愿意从你的第一个建议中迈出第二步:哈哈,很好的尝试从形式上说,你是对的,但是团体的名字是为了更好的理解,可以是任何名字。我真的很喜欢:谢谢!我只是尽可能地遵循接吻原则;。现在我添加了另一个解决方案,但发布了错误的代码块。很抱歉编辑了我的文章好

Sql server Kari,我更愿意从你的第一个建议中迈出第二步:哈哈,很好的尝试从形式上说,你是对的,但是团体的名字是为了更好的理解,可以是任何名字。我真的很喜欢:谢谢!我只是尽可能地遵循接吻原则;。现在我添加了另一个解决方案,但发布了错误的代码块。很抱歉编辑了我的文章好,sql-server,tsql,Sql Server,Tsql,Kari,我更愿意从你的第一个建议中迈出第二步:哈哈,很好的尝试从形式上说,你是对的,但是团体的名字是为了更好的理解,可以是任何名字。我真的很喜欢:谢谢!我只是尽可能地遵循接吻原则;。现在我添加了另一个解决方案,但发布了错误的代码块。很抱歉编辑了我的文章好几次。Kari,谢谢你的第二个解决方案。我同意这是一个非常复杂的过程。Kari,我更愿意从你的第一个建议中迈出第二步:Dwight,谢谢你的例子,但是我希望这个任务可以在没有显式迭代的情况下解决-只需查询。至少我在寻找那种优雅的解决方案。德怀特


Kari,我更愿意从你的第一个建议中迈出第二步:哈哈,很好的尝试从形式上说,你是对的,但是团体的名字是为了更好的理解,可以是任何名字。我真的很喜欢:谢谢!我只是尽可能地遵循接吻原则;。现在我添加了另一个解决方案,但发布了错误的代码块。很抱歉编辑了我的文章好几次。Kari,谢谢你的第二个解决方案。我同意这是一个非常复杂的过程。Kari,我更愿意从你的第一个建议中迈出第二步:Dwight,谢谢你的例子,但是我希望这个任务可以在没有显式迭代的情况下解决-只需查询。至少我在寻找那种优雅的解决方案。德怀特,谢谢你的例子,但是我希望这个任务可以在没有显式迭代的情况下解决——只需查询。至少我在寻找那种优雅的解决方案。
create table #Users (
    Id   int not null,
    Name nvarchar(50) not null,
    constraint PK_Users primary key clustered (Id)
);
create table #Groups (
    Id   int not null,
    Name nvarchar(50) not null, 
    constraint PK_Groups primary key clustered (Id)
);
create table #GroupUsers (
    GroupId int not null ,
    UserId  int not null ,
    constraint PK_GroupUsers primary key clustered (GroupId, UserId),
    constraint FK_GroupUsers_GroupId foreign key (GroupId) references #Groups (Id),
    constraint FK_GroupUsers_UserId foreign key (UserId) references #Users (Id)
);

insert into #Users values (1, 'Anna'), (2, 'Berta'), (3, 'Carlie'), (4, 'Dana'), (5, 'Emil');
insert into #Groups values (1, 'Anna-Berta'), (2, 'Anna-Carlie'), (3, 'Anna-Berta-Carlie');
insert into #GroupUsers values 
(1,1), (1, 2), -- 'Anna-Berta' group
(2,1), (2, 3), -- 'Anna-Carlie' group
(3,1), (3, 2), (3, 3); -- 'Anna-Berta-Carlie' group

declare @sql nvarchar(max) = '';
declare @nextgroupid int = 0;
declare @keyuser int = 0;

select @keyuser = ID from #Users where [Name]='Anna';

while exists (select 1 from #Users u inner join #Users u2 on u.Id=1 where u2.Id not in (select userid from #GroupUsers))
begin

select @nextgroupid = MAX(id)+1 from #Groups;

set @sql = 'insert #groups (id, [name]) select top 1 ' + CAST(@nextgroupid as nvarchar(3)) + ', u.[name] + ''-'' + u2.[name] as missingusergroup from #Users u inner join #Users u2 on u.Id= ' + CAST(@keyuser as nvarchar(3)) + ' where u2.Id not in (select userid from #GroupUsers) order by u2.id;';
exec(@sql);
set @sql = 'insert #groupusers (groupid, userid) select top 1 ' + CAST(@nextgroupid as nvarchar(3)) + ', u2.id from #Users u inner join #Users u2 on u.Id= ' + CAST(@keyuser as nvarchar(3)) + ' where u2.Id not in (select userid from #GroupUsers) union select top 1 '+ CAST(@nextgroupid as nvarchar(3)) +', u.id from #Users u where u.id= ' + CAST(@keyuser as nvarchar(3)) + ' order by u2.id;';
exec(@sql);
end

select * from #GroupUsers;

select * from #Groups;

drop table #Groups, #GroupUsers, #Users;
 select u.Id, p.Id
  from dbo.Users u 
  cross join dbo.Users p
  where u.Id = 1 and p.Id <> 1
    and u.Name + '-' + p.Name not in (select g.Name from dbo.Groups g);
with required_groups as (
   select u.Id as userId, p.Id pairId
    from dbo.Users u 
    cross join dbo.Users p
    where u.Id = 1 and p.Id <> 1
 ),
 existing_groups as (
   select annas_groups.UserId as userId, pairs_groups.UserId as pairId
     from (
       select *
         from GroupUsers gu
         where gu.UserId = 1
           and gu.GroupId in (
             select x.GroupId from GroupUsers x
               group by x.GroupId
               having count(*) = 2
         )
      ) annas_groups
      inner join (
       select *
         from GroupUsers gu
         where 
           gu.UserId <> 1
           and gu.GroupId in (
             select x.GroupId from GroupUsers x
               group by x.GroupId
               having count(*) = 2
         )        
      ) pairs_groups on annas_groups.GroupId = pairs_groups.GroupId
 )

 select * 
   from required_groups rg
   where not exists (
       select 1 
         from existing_groups eg 
         where eg.UserId = rg.UserId 
           and eg.PairId = rg.PairId
   )