Sql server 尝试在Sql Server中执行递归查询

Sql server 尝试在Sql Server中执行递归查询,sql-server,common-table-expression,Sql Server,Common Table Expression,我正在尝试执行一个括号的查询,例如8、16、32、64个团队单淘汰括号。我想知道,考虑到先发种子和比赛,谁赢得了前几场比赛,谁在打谁 我将表定义为: CREATE TABLE [dbo].[MatchGame] ( [MatchGameId] BIGINT IDENTITY (1, 1) NOT NULL, [MatchSizeId] BIGINT NULL, [StartSeedTeamA]

我正在尝试执行一个括号的查询,例如8、16、32、64个团队单淘汰括号。我想知道,考虑到先发种子和比赛,谁赢得了前几场比赛,谁在打谁

我将表定义为:

CREATE TABLE [dbo].[MatchGame] (  
    [MatchGameId]            BIGINT   IDENTITY (1, 1) NOT NULL,  
    [MatchSizeId]            BIGINT   NULL,  
    [StartSeedTeamA]         INT      NULL,  
    [StartSeedTeamB]         INT      NULL,  
    [DateEntered]            DATETIME NULL,  
    [DateUpdated]            DATETIME NULL,  
    [MatchNumber]            INT      NULL,  
    [WinnerPlaysMatchNumber] INT      NULL,  
    [RoundNumber]            INT      NULL,  
    PRIMARY KEY CLUSTERED ([MatchGameId] ASC),  
    CONSTRAINT [FK_MatchGame_MatchSize] FOREIGN KEY ([MatchSizeId]) REFERENCES [dbo].[MatchSize] ([MatchSizeId])  
);  
MatchSizeId只是另一个表的fk,其中包含括号大小和说明。这对讨论来说并不重要。StartSeedTeamA和StartSeedTeamB的值为1,以匹配大小(16、32、64等)。种子值在第一轮中有数字,但在后续轮中为空。matchnumber列的值类似于16队与1队比赛时的值1,8队与9队比赛时的值2,等等。WinnerPlaysMatchNumber列将让第1场比赛的获胜者与第17场比赛中第2场比赛的获胜者进行比赛。舍入数具有表示匹配舍入的值。在16队单淘汰赛中,只有1-4个可能值(第一轮比赛、第二轮比赛、第三轮比赛、第四轮比赛)

我想知道的是,给定一个matchsizeid值,我希望能够查询一个matchnumber,并获得游戏中可能出现的种子数的允许值。我从另一张桌子上知道谁赢了比赛。我希望我可以编写一个sql server cte来实现这一点,但我的sql fu很弱。我试过下面这样的方法,但不知道是否有用

with matchgames_cte (StartSeedTeamA, StartSeedTeamB, MatchNumber,  
    MatchSizeId, WinnerPlaysMatchNumber, RoundNumber)  
as  
(  
  select StartSeedTeamA, StartSeedTeamB, MatchNumber, MatchSizeId,   
    WinnerPlaysMatchNumber, RoundNumber   
    from MatchGame where RoundNumber = 1  
    UNION ALL  
    select a.StartSeedTeamA, a.StartSeedTeamB, a.MatchNumber, a.MatchSizeId,   
    a.WinnerPlaysMatchNumber, a.roundNumber   
    from MatchGame a INNER JOIN matchgames_cte b on   a.WinnerPlaysMatchNumber=b.matchnumber where a.StartSeedTeamA is null  
)  
我试图用以下查询调用它。 从matchgames中选择*,其中matchnumber=13,matchsizeid=3

不幸的是,除了第一轮结果外,我对cte的任何查询似乎都没有给我任何结果。如有任何建议,我们将不胜感激。谢谢你抽出时间

CREATE FUNCTION [dbo].[fn_StartSeeds]  
(  
    @matchsizeid bigint,  
    @startmatchnumber int  
)  
RETURNS TABLE AS RETURN  
(  
    with matchgames_cte (StartSeedTeamA, StartSeedTeamB, MatchNumber, MatchSizeId, winnerplaysmatchnumber)  
    as  
    (  
      select StartSeedTeamA, StartSeedTeamB, MatchNumber, MatchSizeId, WinnerPlaysMatchNumber
        from MatchGame where MatchNumber = @startmatchnumber and MatchSizeId = @matchsizeid  
        UNION ALL  
        select a.StartSeedTeamA, a.StartSeedTeamB, a.MatchNumber, a.MatchSizeId, a.WinnerPlaysMatchNumber
        from MatchGame a JOIN matchgames_cte b on b.MatchNumber=a.WinnerPlaysMatchNumber where a.WinnerPlaysMatchNumber is not null and a.MatchSizeId = @matchsizeid  
    )  
    select * from matchgames_cte where MatchSizeId=@matchsizeid and StartSeedTeamA is not null  
)  
沃利

以下是所要求的一些数据:

SET IDENTITY_INSERT [dbo].[MatchGame] ON 

GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (1, 1, 1, 4, CAST(N'2016-02-11 21:48:27.370' AS DateTime), CAST(N'2016-02-12 16:03:45.100' AS DateTime), 1, 3, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (2, 1, 2, 3, CAST(N'2016-02-11 21:48:37.863' AS DateTime), CAST(N'2016-02-12 16:03:46.827' AS DateTime), 2, 3, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (3, 1, NULL, NULL, CAST(N'2016-02-11 21:48:45.917' AS DateTime), CAST(N'2016-02-12 16:03:53.080' AS DateTime), 3, NULL, 2)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (4, 2, 1, 8, CAST(N'2016-02-11 21:54:40.783' AS DateTime), CAST(N'2016-02-12 16:03:55.240' AS DateTime), 1, 5, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (5, 2, 5, 4, CAST(N'2016-02-11 21:54:59.317' AS DateTime), CAST(N'2016-02-12 16:03:56.013' AS DateTime), 2, 5, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (6, 2, 3, 6, CAST(N'2016-02-11 21:55:17.287' AS DateTime), CAST(N'2016-02-12 16:03:56.930' AS DateTime), 3, 6, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (7, 2, 2, 7, CAST(N'2016-02-11 21:55:45.730' AS DateTime), CAST(N'2016-02-12 16:03:57.710' AS DateTime), 4, 6, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (8, 2, NULL, NULL, CAST(N'2016-02-11 21:56:12.327' AS DateTime), CAST(N'2016-02-12 16:03:58.883' AS DateTime), 5, 7, 2)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (9, 2, NULL, NULL, CAST(N'2016-02-11 21:56:30.340' AS DateTime), CAST(N'2016-02-12 16:03:59.817' AS DateTime), 6, 7, 2)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (10, 2, NULL, NULL, CAST(N'2016-02-11 21:56:43.483' AS DateTime), CAST(N'2016-02-12 16:04:02.397' AS DateTime), 7, NULL, 3)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (11, 3, 1, 16, CAST(N'2016-02-11 22:12:16.467' AS DateTime), CAST(N'2016-02-12 16:04:06.040' AS DateTime), 1, 9, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (12, 3, 8, 9, CAST(N'2016-02-11 22:12:32.533' AS DateTime), CAST(N'2016-02-12 16:04:06.630' AS DateTime), 2, 9, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (13, 3, 4, 13, CAST(N'2016-02-11 22:12:50.027' AS DateTime), CAST(N'2016-02-12 16:04:07.197' AS DateTime), 3, 10, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (14, 3, 5, 12, CAST(N'2016-02-11 22:13:06.283' AS DateTime), CAST(N'2016-02-12 16:04:08.087' AS DateTime), 4, 10, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (15, 3, 3, 14, CAST(N'2016-02-11 22:13:30.960' AS DateTime), CAST(N'2016-02-12 16:04:08.880' AS DateTime), 5, 11, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (16, 3, 6, 11, CAST(N'2016-02-11 22:13:42.627' AS DateTime), CAST(N'2016-02-12 16:04:09.787' AS DateTime), 6, 11, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (17, 3, 7, 10, CAST(N'2016-02-11 22:14:09.203' AS DateTime), CAST(N'2016-02-12 16:04:11.563' AS DateTime), 7, 12, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (18, 3, 15, 2, CAST(N'2016-02-11 22:14:22.803' AS DateTime), CAST(N'2016-02-12 16:04:13.473' AS DateTime), 8, 12, 1)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (19, 3, NULL, NULL, CAST(N'2016-02-11 22:14:41.130' AS DateTime), CAST(N'2016-02-12 16:04:18.120' AS DateTime), 9, 13, 2)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (20, 3, NULL, NULL, CAST(N'2016-02-11 22:14:48.930' AS DateTime), CAST(N'2016-02-12 16:04:18.777' AS DateTime), 10, 13, 2)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (21, 3, NULL, NULL, CAST(N'2016-02-11 22:15:01.407' AS DateTime), CAST(N'2016-02-12 16:04:19.493' AS DateTime), 11, 14, 2)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (22, 3, NULL, NULL, CAST(N'2016-02-11 22:15:13.843' AS DateTime), CAST(N'2016-02-12 16:04:20.443' AS DateTime), 12, 14, 2)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (23, 3, NULL, NULL, CAST(N'2016-02-11 22:15:23.607' AS DateTime), CAST(N'2016-02-12 16:04:23.297' AS DateTime), 13, 15, 3)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (24, 3, NULL, NULL, CAST(N'2016-02-11 22:15:31.050' AS DateTime), CAST(N'2016-02-12 16:04:24.237' AS DateTime), 14, 15, 3)
GO
INSERT [dbo].[MatchGame] ([MatchGameId], [MatchSizeId], [StartSeedTeamA], [StartSeedTeamB], [DateEntered], [DateUpdated], [MatchNumber], [WinnerPlaysMatchNumber], [RoundNumber]) VALUES (25, 3, NULL, NULL, CAST(N'2016-02-11 22:15:36.730' AS DateTime), CAST(N'2016-02-12 16:04:25.867' AS DateTime), 15, NULL, 4)
GO
SET IDENTITY_INSERT [dbo].[MatchGame] OFF
GO
下面是我尝试运行的一个示例查询:

with matchgames_cte (StartSeedTeamA, StartSeedTeamB, MatchNumber,
    MatchSizeId, WinnerPlaysMatchNumber, RoundNumber)
as
(
  select StartSeedTeamA, StartSeedTeamB, MatchNumber, MatchSizeId, 
    WinnerPlaysMatchNumber, RoundNumber 
    from MatchGame where WinnerPlaysMatchNumber is null
    UNION ALL
    select a.StartSeedTeamA, a.StartSeedTeamB, a.MatchNumber, a.MatchSizeId, 
    a.WinnerPlaysMatchNumber, a.roundNumber 
    from MatchGame a INNER JOIN matchgames_cte b on     b.MatchNumber=a.WinnerPlaysMatchNumber where Not(a.WinnerPlaysMatchNumber is null)
)
select * from matchgames_cte where StartSeedTeamA is not null and MatchNumber=14

看起来您的递归是正确的,但在最后的WHERE子句中,您尝试:

  • MatchNumber
    进行筛选,每个层次结构看起来应该是唯一的(我没有看到MatchNumber=13和MatchNumber=14分别有一行)
  • StartSeedTeamA
    进行筛选,在样本数据中几乎所有位置都为空
这可能有助于找到下一场比赛的种子队:

select next.MatchNumber, prior.StartSeedTeamA, prior.StartSeedTeamB, prior.MatchNumber as FinishedMatchNumber
from MatchGame next
inner join MatchGame prior on next.MatchNumber = prior.WinnerPlaysMatchNumber
where next.StartSeedTeamA is NULL and prior.StartSeedTeamA is not NULL

看起来您的递归是正确的,但在最后的WHERE子句中,您尝试:

  • MatchNumber
    进行筛选,每个层次结构看起来应该是唯一的(我没有看到MatchNumber=13和MatchNumber=14分别有一行)
  • StartSeedTeamA
    进行筛选,在样本数据中几乎所有位置都为空
这可能有助于找到下一场比赛的种子队:

select next.MatchNumber, prior.StartSeedTeamA, prior.StartSeedTeamB, prior.MatchNumber as FinishedMatchNumber
from MatchGame next
inner join MatchGame prior on next.MatchNumber = prior.WinnerPlaysMatchNumber
where next.StartSeedTeamA is NULL and prior.StartSeedTeamA is not NULL

我一直在研究这个问题,最终得出了我认为是答案的结论。我把它贴在下面了。这是我用cte编写的sql server函数。任何关于改进的建议都将不胜感激。谢谢你抽出时间

CREATE FUNCTION [dbo].[fn_StartSeeds]  
(  
    @matchsizeid bigint,  
    @startmatchnumber int  
)  
RETURNS TABLE AS RETURN  
(  
    with matchgames_cte (StartSeedTeamA, StartSeedTeamB, MatchNumber, MatchSizeId, winnerplaysmatchnumber)  
    as  
    (  
      select StartSeedTeamA, StartSeedTeamB, MatchNumber, MatchSizeId, WinnerPlaysMatchNumber
        from MatchGame where MatchNumber = @startmatchnumber and MatchSizeId = @matchsizeid  
        UNION ALL  
        select a.StartSeedTeamA, a.StartSeedTeamB, a.MatchNumber, a.MatchSizeId, a.WinnerPlaysMatchNumber
        from MatchGame a JOIN matchgames_cte b on b.MatchNumber=a.WinnerPlaysMatchNumber where a.WinnerPlaysMatchNumber is not null and a.MatchSizeId = @matchsizeid  
    )  
    select * from matchgames_cte where MatchSizeId=@matchsizeid and StartSeedTeamA is not null  
)  

我一直在研究这个问题,最终得出了我认为是答案的结论。我把它贴在下面了。这是我用cte编写的sql server函数。任何关于改进的建议都将不胜感激。谢谢你抽出时间

CREATE FUNCTION [dbo].[fn_StartSeeds]  
(  
    @matchsizeid bigint,  
    @startmatchnumber int  
)  
RETURNS TABLE AS RETURN  
(  
    with matchgames_cte (StartSeedTeamA, StartSeedTeamB, MatchNumber, MatchSizeId, winnerplaysmatchnumber)  
    as  
    (  
      select StartSeedTeamA, StartSeedTeamB, MatchNumber, MatchSizeId, WinnerPlaysMatchNumber
        from MatchGame where MatchNumber = @startmatchnumber and MatchSizeId = @matchsizeid  
        UNION ALL  
        select a.StartSeedTeamA, a.StartSeedTeamB, a.MatchNumber, a.MatchSizeId, a.WinnerPlaysMatchNumber
        from MatchGame a JOIN matchgames_cte b on b.MatchNumber=a.WinnerPlaysMatchNumber where a.WinnerPlaysMatchNumber is not null and a.MatchSizeId = @matchsizeid  
    )  
    select * from matchgames_cte where MatchSizeId=@matchsizeid and StartSeedTeamA is not null  
)  

你能发布一些样本数据吗?如果您发布了正在尝试的实际查询,也会有所帮助。您是否尝试过将联接条件从
a.winnerplaysmachnumber=b.matchnumber
切换到
b.winnerplaysmachnumber=a.matchnumber
?我认为
winnerplaysmachnumber
应该来自CTE,并加入
MatchRound
表上的匹配号码。谢谢Sean。我添加了一些数据,尽管在这个问题上看起来很可怕。对此表示歉意。韦恩,我也尝试过这种改变,但没有成功。我一直在看这个,最后我找到了我认为是答案。我把它贴在下面了。这是我用cte写的sql server函数。你能发布一些示例数据吗?如果您发布了正在尝试的实际查询,也会有所帮助。您是否尝试过将联接条件从
a.winnerplaysmachnumber=b.matchnumber
切换到
b.winnerplaysmachnumber=a.matchnumber
?我认为
winnerplaysmachnumber
应该来自CTE,并加入
MatchRound
表上的匹配号码。谢谢Sean。我添加了一些数据,尽管在这个问题上看起来很可怕。对此表示歉意。韦恩,我也尝试过这种改变,但没有成功。我一直在看这个,最后我找到了我认为是答案。我把它贴在下面了。这是我用cte编写的sql server函数。