SQL锦标赛日期生成器

时间:2017-12-14 14:53:12

标签: sql sql-server database tsql

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

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

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;

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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中指定的预期输出相同。