T-SQL 自加入 Table 与外部 Table 分组
T-SQL Self Join Table with External Table Grouping
期望的结果是根据第二组对第一组进行分组。有一群人要配给其他人,隔着"rooms"所以每个房间统一使用。因此,如果有 5 个人和 7 个房间,则有 20 种组合,因此每个房间的使用次数不会超过 3 次(切线:每个房间按顺序使用,因此不会有一个人一次出现在多个地方的危险)。每组有 3 对,但随着添加额外的组行,每组的对数应该减少;如果删除了额外的组行,则每组的对数应该增加。如果我不是在 Sets 中思考,它感觉就像一个 RBAR 操作,因为我只希望每个房间用作人数组合除以组数 - 20 个组合/7 个组 = 每组 3 个组合,但是 20组合 / 5 组 = 每组 4 种组合。
结果集目前看起来像这样:
person1 person2
person1 person3
person1 person4
person1 person5
person2 person1
person2 person3
person2 person4
person2 person5
person3 person1
person3 person2
person3 person4
person3 person5
person4 person1
person4 person2
person4 person3
person4 person5
person5 person1
person5 person2
person5 person3
person5 person4
但我正在想办法让它看起来像这样:
01-01 person1 person2
01-01 person1 person3
01-01 person1 person4
01-02 person1 person5
01-02 person2 person1
01-02 person2 person3
01-03 person2 person4
01-03 person2 person5
01-03 person3 person1
01-04 person3 person2
01-04 person3 person4
01-04 person3 person5
01-05 person4 person1
01-05 person4 person2
01-05 person4 person3
01-06 person4 person5
01-06 person5 person1
01-06 person5 person2
01-07 person5 person3
01-07 person5 person4
这是T-SQL我目前拥有的:
If Object_Id('TempDb..#namez') Is Not Null
Drop Table #namez
Create Table #namez
(
namezId Int Not Null Primary Key,
membername VarChar(48)
)
Insert Into #namez
Values (10 ,'person1'), (11 , 'person2'),
(12 , 'person3'), (13 , 'person4'),
(14 , 'person5')
If Object_Id('TempDb..#groups') Is Not Null
Drop Table #groups
Create Table #groups
(
groupsId Int Not Null Primary Key,
GroupCode Char(5)
)
Insert Into #groups
Values (10, '01-01'), (11, '01-02'), (12, '01-03'),
(13, '01-04'), (14, '01-05'), (15, '01-06'), (16, '01-07')
Select
TeamOne.membername, TeamTwo.membername
From
#namez TeamOne
Full Outer Join
#namez TeamTwo On TeamOne.membername != TeamTwo.membername
order by
teamone.membername, teamtwo.membername
谢谢!
您可以使用CROSS JOIN
Select TeamOne.membername , TeamTwo.membername
From #namez TeamOne
cross join #namez TeamTwo
where TeamOne.membername != TeamTwo.membername
order by teamone.membername,teamtwo.membername
对现有内容进行一些调整。
我们使用 row_number() 根据我们需要如何拆分团队来对团队进行分组。然后使用它,加上 min() GroupId 加入组 table.
这假设组 table 中的 GroupId 是连续的,并且应该考虑或多或少的团队和或多或少的组。
试一试:
IF OBJECT_ID('TempDb..#namez') IS NOT NULL
DROP TABLE [#namez];
CREATE TABLE [#namez]
(
[namezId] INT NOT NULL PRIMARY KEY
, [membername] VARCHAR(48)
);
INSERT INTO [#namez]
VALUES ( 10, 'person1' )
, ( 11, 'person2' )
, ( 12, 'person3' )
, ( 13, 'person4' )
, ( 14, 'person5' );
IF OBJECT_ID('TempDb..#groups') IS NOT NULL
DROP TABLE [#groups];
CREATE TABLE [#groups]
(
[groupsId] INT NOT NULL PRIMARY KEY
, [GroupCode] CHAR(5)
);
INSERT INTO [#groups]
VALUES ( 10, '01-01' )
, ( 11, '01-02' )
, ( 12, '01-03' )
, ( 13, '01-04' )
, ( 14, '01-05' )
, ( 15, '01-06' )
, ( 16, '01-07' );
DECLARE @GroupComboCount INT
, @GroupCount DECIMAL(12, 2)
, @TeamCount DECIMAL(12, 2)
, @MinGroupId INT;
--What is our group count
SET @GroupCount = (
SELECT COUNT(*)
FROM [#groups]
);
--What is our team count
SET @TeamCount = (
SELECT COUNT(*)
FROM [#namez] [TeamOne]
FULL OUTER JOIN [#namez] [TeamTwo]
ON [TeamOne].[membername] != [TeamTwo].[membername]
);
--How should I uniformly split the teams
SET @GroupComboCount = ROUND(@TeamCount / @GroupCount, 0);
--What is the min group so I can build my relationship back to groups.
SET @MinGroupId = (
SELECT MIN([groupsId])
FROM [#groups]
);
SELECT grp.*, [TeamGroups].*
FROM (
SELECT ( ROW_NUMBER() OVER ( ORDER BY [TeamOne].[membername]
, [TeamTwo].[membername]
) + ( @GroupComboCount - 1 )
) / @GroupComboCount AS [TeamGrouping] --This does my group based on the @GroupComboCount
, [TeamOne].[membername] AS [Member1]
, [TeamTwo].[membername] AS [Member2]
FROM [#namez] [TeamOne]
FULL OUTER JOIN [#namez] [TeamTwo]
ON [TeamOne].[membername] != [TeamTwo].[membername]
) AS [TeamGroups]
INNER JOIN [#groups] grp ON grp.[groupsId] = @MinGroupId+[TeamGroups].[TeamGrouping]-1 --Here we then relate that back to my groups.
ORDER BY [TeamGroups].[Member1]
, [TeamGroups].[Member2];
期望的结果是根据第二组对第一组进行分组。有一群人要配给其他人,隔着"rooms"所以每个房间统一使用。因此,如果有 5 个人和 7 个房间,则有 20 种组合,因此每个房间的使用次数不会超过 3 次(切线:每个房间按顺序使用,因此不会有一个人一次出现在多个地方的危险)。每组有 3 对,但随着添加额外的组行,每组的对数应该减少;如果删除了额外的组行,则每组的对数应该增加。如果我不是在 Sets 中思考,它感觉就像一个 RBAR 操作,因为我只希望每个房间用作人数组合除以组数 - 20 个组合/7 个组 = 每组 3 个组合,但是 20组合 / 5 组 = 每组 4 种组合。
结果集目前看起来像这样:
person1 person2
person1 person3
person1 person4
person1 person5
person2 person1
person2 person3
person2 person4
person2 person5
person3 person1
person3 person2
person3 person4
person3 person5
person4 person1
person4 person2
person4 person3
person4 person5
person5 person1
person5 person2
person5 person3
person5 person4
但我正在想办法让它看起来像这样:
01-01 person1 person2
01-01 person1 person3
01-01 person1 person4
01-02 person1 person5
01-02 person2 person1
01-02 person2 person3
01-03 person2 person4
01-03 person2 person5
01-03 person3 person1
01-04 person3 person2
01-04 person3 person4
01-04 person3 person5
01-05 person4 person1
01-05 person4 person2
01-05 person4 person3
01-06 person4 person5
01-06 person5 person1
01-06 person5 person2
01-07 person5 person3
01-07 person5 person4
这是T-SQL我目前拥有的:
If Object_Id('TempDb..#namez') Is Not Null
Drop Table #namez
Create Table #namez
(
namezId Int Not Null Primary Key,
membername VarChar(48)
)
Insert Into #namez
Values (10 ,'person1'), (11 , 'person2'),
(12 , 'person3'), (13 , 'person4'),
(14 , 'person5')
If Object_Id('TempDb..#groups') Is Not Null
Drop Table #groups
Create Table #groups
(
groupsId Int Not Null Primary Key,
GroupCode Char(5)
)
Insert Into #groups
Values (10, '01-01'), (11, '01-02'), (12, '01-03'),
(13, '01-04'), (14, '01-05'), (15, '01-06'), (16, '01-07')
Select
TeamOne.membername, TeamTwo.membername
From
#namez TeamOne
Full Outer Join
#namez TeamTwo On TeamOne.membername != TeamTwo.membername
order by
teamone.membername, teamtwo.membername
谢谢!
您可以使用CROSS JOIN
Select TeamOne.membername , TeamTwo.membername
From #namez TeamOne
cross join #namez TeamTwo
where TeamOne.membername != TeamTwo.membername
order by teamone.membername,teamtwo.membername
对现有内容进行一些调整。
我们使用 row_number() 根据我们需要如何拆分团队来对团队进行分组。然后使用它,加上 min() GroupId 加入组 table.
这假设组 table 中的 GroupId 是连续的,并且应该考虑或多或少的团队和或多或少的组。
试一试:
IF OBJECT_ID('TempDb..#namez') IS NOT NULL
DROP TABLE [#namez];
CREATE TABLE [#namez]
(
[namezId] INT NOT NULL PRIMARY KEY
, [membername] VARCHAR(48)
);
INSERT INTO [#namez]
VALUES ( 10, 'person1' )
, ( 11, 'person2' )
, ( 12, 'person3' )
, ( 13, 'person4' )
, ( 14, 'person5' );
IF OBJECT_ID('TempDb..#groups') IS NOT NULL
DROP TABLE [#groups];
CREATE TABLE [#groups]
(
[groupsId] INT NOT NULL PRIMARY KEY
, [GroupCode] CHAR(5)
);
INSERT INTO [#groups]
VALUES ( 10, '01-01' )
, ( 11, '01-02' )
, ( 12, '01-03' )
, ( 13, '01-04' )
, ( 14, '01-05' )
, ( 15, '01-06' )
, ( 16, '01-07' );
DECLARE @GroupComboCount INT
, @GroupCount DECIMAL(12, 2)
, @TeamCount DECIMAL(12, 2)
, @MinGroupId INT;
--What is our group count
SET @GroupCount = (
SELECT COUNT(*)
FROM [#groups]
);
--What is our team count
SET @TeamCount = (
SELECT COUNT(*)
FROM [#namez] [TeamOne]
FULL OUTER JOIN [#namez] [TeamTwo]
ON [TeamOne].[membername] != [TeamTwo].[membername]
);
--How should I uniformly split the teams
SET @GroupComboCount = ROUND(@TeamCount / @GroupCount, 0);
--What is the min group so I can build my relationship back to groups.
SET @MinGroupId = (
SELECT MIN([groupsId])
FROM [#groups]
);
SELECT grp.*, [TeamGroups].*
FROM (
SELECT ( ROW_NUMBER() OVER ( ORDER BY [TeamOne].[membername]
, [TeamTwo].[membername]
) + ( @GroupComboCount - 1 )
) / @GroupComboCount AS [TeamGrouping] --This does my group based on the @GroupComboCount
, [TeamOne].[membername] AS [Member1]
, [TeamTwo].[membername] AS [Member2]
FROM [#namez] [TeamOne]
FULL OUTER JOIN [#namez] [TeamTwo]
ON [TeamOne].[membername] != [TeamTwo].[membername]
) AS [TeamGroups]
INNER JOIN [#groups] grp ON grp.[groupsId] = @MinGroupId+[TeamGroups].[TeamGrouping]-1 --Here we then relate that back to my groups.
ORDER BY [TeamGroups].[Member1]
, [TeamGroups].[Member2];