我正在尝试创建一个锦标赛,每个球队在主场和客场之后都会相互比赛。
我想生成一个日期,以便每个星期五的球队都会互相比赛
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;
答案 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 2
和Team 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
中指定的预期输出相同。