SQL锦标赛日期生成器

问题描述 投票:-2回答:2

我正在努力创建一个锦标赛,每个球队都会在主场和客场之间互相比赛。

我想生成一个日期,这样每个星期五的球队都会互相比赛

TempExampletable显示每个团队每周播放一次的最终结果。

TempExampletable2显示了我当前拥有的数据以及我将用于生成日期的内容。

DROP TABLE TempExampletable;
DROP TABLE TempExampletable2;

CREATE TABLE TempExampletable(
Home VARCHAR(100),
Away VARCHAR (100),
    Playing DATETIME
)

INSERT INTO TempExampletable VALUES
('Team 1', 'Team 2', '2017/12/01 17:30:00'),
('Team 1', 'Team 3', '2017/12/08 17:30:00'),
('Team 1', 'Team 4', '2017/12/15 17:30:00'),
('Team 2', 'Team 1', '2017/12/22 17:30:00'),
('Team 2', 'Team 3', '2017/12/15 17:30:00'),
('Team 2', 'Team 4', '2017/12/08 17:30:00'),
('Team 3', 'Team 1', '2017/12/29 17:30:00'),
('Team 3', 'Team 2', '2018/11/05 17:30:00'),
('Team 3', 'Team 4', '2017/12/01 17:30:00'),
('Team 4', 'Team 1', '2018/01/05 17:30:00'),
('Team 4', 'Team 2', '2017/12/29 17:30:00'),
('Team 4', 'Team 3', '2017/12/22 17:30:00')

CREATE TABLE TempExampletable2(
Home VARCHAR(100),
Away VARCHAR (100),
    Playing DATETIME
)

INSERT INTO TempExampletable2(Home, Away) VALUES
('Team 1', 'Team 2'),
('Team 1', 'Team 3'),
('Team 1', 'Team 4'),
('Team 2', 'Team 1'),
('Team 2', 'Team 3'),
('Team 2', 'Team 4'),
('Team 3', 'Team 1'),
('Team 3', 'Team 2'),
('Team 3', 'Team 4'),
('Team 4', 'Team 1'),
('Team 4', 'Team 2'),
('Team 4', 'Team 3')

SELECT * FROM TempExampletable2 ORDER BY Playing ASC;
SELECT * FROM TempExampletable ORDER BY Playing ASC;
sql sql-server database tsql
2个回答
0
投票

这是一个解决方案。请根据需要格式化日期,或者可以插入日期时间列

WITH teams AS
(SELECT Home, Away, 
       row_number() over(order by Home, Away) - 1 AS r_num
  FROM TempExampletable2 )
SELECT Home, Away, DATEADD(week, r_num, '2017/12/01 17:30:00') AS Playing
  FROM teams
  ORDER BY Playing ASC; 

产量

Home    Away    Playing
Team 1  Team 2  2017-12-01T17:30:00Z
Team 1  Team 3  2017-12-08T17:30:00Z
Team 1  Team 4  2017-12-15T17:30:00Z
Team 2  Team 1  2017-12-22T17:30:00Z
Team 2  Team 3  2017-12-29T17:30:00Z
Team 2  Team 4  2018-01-05T17:30:00Z
Team 3  Team 1  2018-01-12T17:30:00Z
Team 3  Team 2  2018-01-19T17:30:00Z
Team 3  Team 4  2018-01-26T17:30:00Z
Team 4  Team 1  2018-02-02T17:30:00Z
Team 4  Team 2  2018-02-09T17:30:00Z
Team 4  Team 3  2018-02-16T17:30:00Z

0
投票

你知道,因为有4支队伍,每周有2场比赛。如果在给定的一周内你安排了一场比赛,你知道第二场比赛不能让第一场比赛的参赛者参与其中。 (Team 1不能同时播放Team 2Team 3,无论Home / Away决定)这种情况使得很难在基于集合的方法中处理这个问题,在这种方法中你将使用递归CTE或其他方法。

以上是为什么我写了一个双嵌套的while循环来安排锦标赛赛季。第一个循环用于逐周进行,第二个循环用于每次迭代中的匹配。

样本数据:

我将示例数据简化为团队列表,然后创建TempExampletable2中显示的对齐

create table #team_table
    (
        Team char(6) not null
    )

insert into #team_table
values ('Team 1')
    , ('Team 2')
    , ('Team 3')
    , ('Team 4')

回答:

create table #matchups
    (
        Home char(6) not null
        , Away char(6) not null
    )

create table #schedule
    (
        Home char(6) not null
        , Away char(6) not null
        , Playing datetime not null
    )

insert into #matchups
select h.Team as Home
, a.Team as Away
from #team_table as h
cross join #team_table as a
where 1=1
and h.Team <> a.Team

declare @bgn_dt datetime = '2017-12-01 17:30:00'
    , @tm_cnt int = (select count(*) from #team_table)
    , @i int = 1
    , @j int
    , @j_max int
    , @wk_cnt int
    , @rnd int
    , @cur_dt datetime;

set @wk_cnt = ((@tm_cnt * (@tm_cnt - 1)) / 2)

set @j_max = (@tm_cnt / 2) --games in a week

while @i <= @wk_cnt
begin --while i

    set @cur_dt = dateadd(d, 7 * (@i - 1), @bgn_dt)

    set @j = 1

    while @j <= @j_max
    begin

        ; with sched_teams as
            (
                select s.Home as Team
                from #schedule as s
                where 1=1
                and s.Playing = @cur_dt
                union all
                select s.Away as Team
                from #schedule as s
                where 1=1
                and s.Playing = @cur_dt         
            )
        insert into #schedule
        select top 1 m.Home
        , m.Away
        , @cur_dt as Playing
        from #matchups as m
        left join sched_teams as sh on m.Home = sh.Team --same team can't play 2 games in a single week
        left join sched_teams as sa on m.Away = sa.Team --same team can't play 2 games in a single week
        left join #schedule as s on m.Home = s.Home --can't play the same matchup twice
                                and m.Away = s.Away
        where 1=1
        and sh.Team is Null
        and sa.Team is Null
        and s.Home is Null
        and s.Away is Null
        order by m.Home asc
        , m.Away asc

        set @j += 1

    end

    set @i += 1

end --while i

select *
from #schedule
order by Home
, Away

order by语句中的insert...select仅用于强制输出与TempExampletable中指定的预期输出相同。

© www.soinside.com 2019 - 2024. All rights reserved.