简体   繁体   English

在SQL Server中生成锦标赛时间表

[英]Generate tournament schedule in SQL Server

I need to take a table that has the names of an even number of teams and with those generate a schedule for a tournament, ie if there where 4 teams: team1, team2, team3 and team4 in the table with the names, then the resulting table would look like the following 我需要使用一个表,该表具有偶数个球队的名称,并使用这些表生成锦标赛的时间表,即,如果在该表中有4个球队:team1,team2,team3和team4,且名称相同,则结果表格如下所示

Team    Team     Round
-----------------------
team1   team2    1
team 3  team4    1
team1   team3    2
team2   team4    2
team1   team4    3
team2   team3    3

I need to do this using T-SQL. 我需要使用T-SQL进行此操作。 I have tried using the Round Robin Tournament algorithm, but I do not know how to implement it in T-SQL. 我曾经尝试使用Round Robin Tournament算法,但是我不知道如何在T-SQL中实现它。

Seeing as no one else has given this an answer, I figure I might as well show you one (probably inefficient) way of doing this with dynamic SQL: 看到没有其他人对此给出答案,我想我也向您展示一种使用动态SQL的方式(可能效率不高):

DECLARE @SQL NVARCHAR(MAX) = N'';
SELECT TOP (SELECT CASE COUNT(*) % 2 WHEN 1 THEN COUNT(*) ELSE COUNT(*) - 1 END FROM dbo.Teams) @SQL += N' UNION ALL
SELECT *
FROM
(
    SELECT TOP (SELECT COUNT(*) / 2 FROM T) 
        Team, 
        RN, 
        RoundNum = ' + CAST(N AS NVARCHAR(3)) + N', 
        Match = ROW_NUMBER() OVER (ORDER BY CASE WHEN RN = 1 THEN 0 ELSE 1 END, (RN + ' + CAST(N - 2 AS NVARCHAR(3)) + N') % (SELECT COUNT(*) FROM T)),
        Slot = 1
    FROM T
    ORDER BY CASE WHEN RN = 1 THEN 0 ELSE 1 END, (RN + ' + CAST(N - 2 AS NVARCHAR(3)) + N') % (SELECT COUNT(*) FROM T)
    UNION ALL
    SELECT TOP (SELECT COUNT(*) / 2 FROM T) 
        Team, 
        RN, 
        RoundNum = ' + CAST(N AS NVARCHAR(3)) + N', 
        Match = ROW_NUMBER() OVER (ORDER BY CASE WHEN RN = 1 THEN 1 ELSE 0 END, (RN + ' + CAST(N - 2 AS NVARCHAR(3)) + N') % (SELECT COUNT(*) FROM T) DESC),
        Slot = 2
    FROM T
    ORDER BY CASE WHEN RN = 1 THEN 1 ELSE 0 END, (RN + ' + CAST(N - 2 AS NVARCHAR(3)) + N') % (SELECT COUNT(*) FROM T) DESC
) AS T
'
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM sys.objects) T(N)
ORDER BY N;

SELECT @SQL = N'
WITH T AS 
(
    SELECT Team, RN = ROW_NUMBER() OVER (ORDER BY Team) 
    FROM dbo.Teams 
    UNION ALL 
    SELECT ''Bye'', COUNT(*) + 1 
    FROM dbo.Teams 
    HAVING COUNT(*) % 2 = 1
),
CTE2 AS 
(
' + STUFF(@SQL, 1, 11, '') + N'
)
SELECT T1.RoundNum, T1.Match, Team1 = T1.Team, Team2 = T2.Team
FROM
(
    SELECT *
    FROM CTE2
    WHERE Slot = 1
) AS T1 JOIN
(
    SELECT *
    FROM CTE2
    WHERE Slot = 2
) AS T2
    ON T2.RoundNum = T1.RoundNum
    AND T2.Match = T1.Match;';


EXEC sp_executesql @SQL;

Essentially, it does the fix one of the contributors in the first or last column of the table described in your wiki link by rooting 1 in place and shifting all the teams around 1. For odd-numbered teams, it adds a 'bye' opponent. 从本质上讲,它通过在位置上扎根1并移动所有团队1来解决wiki链接fix one of the contributors in the first or last column of the table 。对于奇数团队,它添加了一个“再见”对手。 And it just cycles through the table either N or N-1 times (depending on whether there's an even or odd amount of teams). 而且它只是在表中循环N或N-1次(取决于是否有偶数或奇数的团队)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM