Таблица самообъединения T-SQL с группировкой внешних таблиц - PullRequest
0 голосов
/ 30 ноября 2018

Желаемым результатом будет группировка первого набора по второму.Существует группа людей, которых нужно сопоставить с другими людьми, разделенными «комнатами», чтобы каждая комната использовалась одинаково.Таким образом, для 5 человек и 7 комнат существует 20 комбинаций, поэтому каждая комната будет использоваться не более 3 раз (касательная: каждая комната используется последовательно, поэтому нет опасности, что человек будет находиться в более чем одном месте одновременно).В группе 3 пары, но по мере добавления строк дополнительных групп число пар в группе должно уменьшаться;если удаляются строки дополнительных групп, то количество пар на группу должно увеличиваться.Если я не думал о множествах, это похоже на операцию 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

Спасибо!

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Несколько настроек к тому, что у вас было.

Мы используем row_number (), чтобы получить группировку команд, основанную на том, как нам нужно их разделить.Затем используйте это, плюс min () GroupId, чтобы присоединиться к таблице групп.

Предполагается, что 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];
0 голосов
/ 30 ноября 2018

Вы можете использовать CROSS JOIN

DB FIDDLE

Select     TeamOne.membername , TeamTwo.membername 
From       #namez TeamOne 
cross join #namez TeamTwo
where      TeamOne.membername != TeamTwo.membername 
order by   teamone.membername,teamtwo.membername
...