将WHILE循环方法更改为基于集合的逻辑

时间:2016-07-24 18:31:59

标签: sql sql-server

下面有一个存储过程,根据执行产品时传递的参数确定一个fixture表:

'LL'表示最后16支队伍 'QF'意味着最后8支球队 'SF'意味着最后4支球队 'FF'意味着最后两支队伍

几乎失败的球队被淘汰以缩短每个阶段的球队。下面的过程有效但实际上我想知道我是否可以将三个WHILE LOOPS替换为更多基础的东西,看看是否有人知道如何操纵代码来包含它?

以下是程序:

-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE [dbo].[InsertFixture_EUCompetition]
    -- Add the parameters for the stored procedure here
    -- exec InsertFixture_EUCompetition 1
    @SeasonID INT,
    @MatchType CHAR(2)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @WeekNumber INT
    DECLARE @FixtureDate DATE
    DECLARE @HomeTeamID INT
    DECLARE @AwayTeamID INT
    DECLARE @LeagueID INT
    -- Insert statements for procedure here
    SELECT * INTO #TempCompetition FROM [dbo].[EUCompetition] where SeasonID = @SeasonID
    -- SELECT * FROM  [dbo].[EUCompetition] where SeasonID = 1

    set @WeekNumber = 1
    set @FixtureDate = GETDATE()

     WHILE((SELECT COUNT(1) FROM #TempCompetition) > 0)
     BEGIN   

     SELECT @LeagueID =  MAX(LeagueID) from #TempCompetition

     IF @MatchType = 'LL'
     BEGIN
     INSERT EUFixture ( MatchType, WeekNumber, FixtureDate, HomeTeamID, HomeScore, AwayTeamID, AwayScore, HomeTeamResult, AwayTeamResult, LeagueID, CurrentSeason) 
     VALUES ( @MatchType, @WeekNumber , @FixtureDate,
      ( Select  TeamId from #TempCompetition where Position = 1 and LeagueID = @LeagueID ) , null,
      ( Select TeamId from #TempCompetition where Position = 4 and LeagueID = @LeagueID ) , null,
      null, null, @LeagueID , @SeasonID )

       INSERT EUFixture (MatchType, WeekNumber, FixtureDate, HomeTeamID, HomeScore, AwayTeamID, AwayScore, HomeTeamResult, AwayTeamResult, LeagueID, CurrentSeason) 
     VALUES (  @MatchType, @WeekNumber , @FixtureDate,
      ( Select TeamId from #TempCompetition where Position = 2 and LeagueID = @LeagueID ) , null,
      ( Select TeamId from #TempCompetition where Position = 3 and LeagueID = @LeagueID ) , null,
      null, null, @LeagueID , @SeasonID )
    RETURN
    END

    DELETE #TempCompetition WHERE LeagueID = @LeagueID
    set @WeekNumber  = @WeekNumber  + 1
    set @FixtureDate = DATEADD(day,1,@FixtureDate)
     END

    DROP TABLE #TempCompetition

    DECLARE @I INT

    IF @MatchType = 'QF'
    SET @I = 1
    WHILE(@I < 5)
    BEGIN
    set @WeekNumber  = @WeekNumber  + 1
    set @FixtureDate = DATEADD(day,1,@FixtureDate)
     INSERT EUFixture (MatchType, WeekNumber, FixtureDate, HomeTeamID, HomeScore, AwayTeamID, AwayScore, HomeTeamResult, AwayTeamResult, LeagueID, CurrentSeason) 
      VALUES (  'QF' , @WeekNumber, @FixtureDate , NULL, NULL,NULL,NULL,NULL,NULL,NULL,@SeasonID )
     SET @I = @I +1
    END


    IF @MatchType = 'SF'
    SET @I = 1
    WHILE(@I < 3)
    BEGIN
    set @WeekNumber  = @WeekNumber  + 1
    set @FixtureDate = DATEADD(day,1,@FixtureDate)
     INSERT EUFixture (MatchType, WeekNumber, FixtureDate, HomeTeamID, HomeScore, AwayTeamID, AwayScore, HomeTeamResult, AwayTeamResult, LeagueID, CurrentSeason) 
      VALUES (  'SF' , @WeekNumber, @FixtureDate , NULL, NULL,NULL,NULL,NULL,NULL,NULL,@SeasonID )
     SET @I = @I +1
    END


    IF @MatchType = 'FF'
    SET @I = 1
    WHILE(@I < 2)
    BEGIN
    set @WeekNumber  = @WeekNumber  + 1
    set @FixtureDate = DATEADD(day,1,@FixtureDate)
     INSERT EUFixture (MatchType, WeekNumber, FixtureDate, HomeTeamID, HomeScore, AwayTeamID, AwayScore, HomeTeamResult, AwayTeamResult, LeagueID, CurrentSeason) 
      VALUES (  'FF' , @WeekNumber, @FixtureDate , NULL, NULL,NULL,NULL,NULL,NULL,NULL,@SeasonID )
     SET @I = @I +1
    END


END

非常感谢

1 个答案:

答案 0 :(得分:1)

尝试这样的事情:

create procedure dbo.InsertAwesome (
    @SeasonID INT,
    @MatchType CHAR(2)
    )
as
begin
set nocount on
insert EUFixture (
    MatchType,
    WeekNumber,
    FixtureDate,
    HomeTeamID,
    AwayTeamID,
    LeagueID,
    CurrentSeason
    )
select @MatchType,
    row_number() over (order by LeagueID) as WeekNumber,
    dateadd(dd, row_number() over (order by LeagueID), getdate()) as FixtureDate,
    min(TeamId),
    max(Teamed),
    LeagueID,
    @SeasonID
from    EUCompetition
where SeasonID = @SeasonID
group by LeagueID,
    case when Position in (1, 4) then 1 else 2 end

—You can do the same with the rest of the queries

end