在SQL Server中生成比赛日程

在SQL Server中生成比赛日程,sql,sql-server,tsql,Sql,Sql Server,Tsql,我需要取一个表,其中包含偶数个球队的名称,并使用这些名称生成一个锦标赛的时间表,即如果表中有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 我需要

我需要取一个表,其中包含偶数个球队的名称,并使用这些名称生成一个锦标赛的时间表,即如果表中有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

我需要使用T-SQL来实现这一点。我已经尝试过使用该算法,但我不知道如何在T-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;
从本质上讲,它通过将1根放在适当的位置,并将所有团队围绕1移动,来修复wiki链接中描述的表的第一列或最后一列中的一个贡献者。对于奇数队,它会添加一个“再见”对手。它只是在表中循环N次或N-1次(取决于团队数量是偶数还是奇数)