我是SQL
的新手,我正试图制作一张存储足球联赛时间表的表格。该表包含4列(matchID, home_team, away_team, match_date
)。我有8支不同的球队,每支球队应该与其他球队进行两次比赛。比赛将持续14周(每周4场比赛)。我搜索并发现double round robin algorithm
做了同样的事情,但我不确定如何在PL / SQL中编写它并生成一个表。请帮帮我。
答案 0 :(得分:0)
您可以使用此查询为您的表生成记录。请注意,我没有强制执行任何由您决定的constraints
,应该。您可以使用所有数据类型和约束编写简单的CREATE TABLE (
语法,并将此查询用于insert
条记录。
match_groups 会生成匹配组合
All_matches 通过交换主队和客队来重复比赛。
CREATE TABLE MATCH_SCHEDULE AS WITH TEAMS (name) AS
(SELECT 'TEAM1'
FROM DUAL
UNION ALL SELECT 'TEAM2'
FROM DUAL
UNION ALL SELECT 'TEAM3'
FROM DUAL
UNION ALL SELECT 'TEAM4'
FROM DUAL
UNION ALL SELECT 'TEAM5'
FROM DUAL
UNION ALL SELECT 'TEAM6'
FROM DUAL
UNION ALL SELECT 'TEAM7'
FROM DUAL
UNION ALL SELECT 'TEAM8'
FROM DUAL),
match_groups AS
(SELECT t1.name home_team,
t2.name away_team
FROM
(SELECT rownum RNUM,
NAME
FROM TEAMS) t1
JOIN
(SELECT rownum RNUM,
NAME
FROM TEAMS) t2 ON t1.RNUM < t2.RNUM),
All_matches AS
(SELECT home_team,
away_team
FROM match_groups
UNION ALL SELECT away_team home_team,
home_team away_team
FROM match_groups)
SELECT ROWNUM matchID,
home_team,
away_team,
SYSDATE + ROWNUM match_date
FROM All_matches;
这将创建一个包含以下数据的表。
表 MATCH_SCHEDULE
MATCHID HOME_TEAM AWAY_TEAM MATCH_DATE
1 TEAM1 TEAM2 09-OCT-17
2 TEAM1 TEAM3 10-OCT-17
3 TEAM1 TEAM4 11-OCT-17
4 TEAM1 TEAM5 12-OCT-17
5 TEAM1 TEAM6 13-OCT-17
6 TEAM1 TEAM7 14-OCT-17
...
...
54 TEAM7 TEAM6 01-DEC-17
55 TEAM8 TEAM6 02-DEC-17
56 TEAM8 TEAM7 03-DEC-17
请注意,MATCHID
只有1,2,3 ....如果您愿意,也可以使用Oracle sequence
或相应地更新它。现在,由于您需要每周进行4次匹配,因此您需要根据需要构建一个adhoc update
脚本并使用正确的日期并运行它。
答案 1 :(得分:0)
Oracle 11g R2架构设置:
CREATE TABLE matches ( matchID, home_team, away_team, match_date ) AS
WITH rounds ( round, home, away, num_players ) AS (
SELECT 1,
LEVEL,
num_players + 1 - LEVEL,
num_players
FROM ( SELECT 8 AS num_players FROM DUAL )
CONNECT BY LEVEL <= num_players / 2
UNION ALL
SELECT round + 1,
CASE home
WHEN 1 THEN 1
WHEN 2 THEN num_players
ELSE home - 1
END,
CASE away
WHEN 2 THEN num_players
ELSE away - 1
END,
num_players
FROM rounds
WHERE round < num_players - 1
)
SELECT ROWNUM,
t.*
FROM (
SELECT home,
away,
DATE '2017-01-01' + ( round - 1 ) * 7 AS match_date
FROM rounds
UNION ALL
SELECT away,
home,
DATE '2017-01-01' + ( round + num_players - 2 ) * 7
FROM rounds
) t;
查询1 :
SELECT * FROM matches
<强> Results 强>:
| MATCHID | HOME_TEAM | AWAY_TEAM | MATCH_DATE |
|---------|-----------|-----------|----------------------|
| 1 | 1 | 8 | 2017-01-01T00:00:00Z |
| 2 | 2 | 7 | 2017-01-01T00:00:00Z |
| 3 | 3 | 6 | 2017-01-01T00:00:00Z |
| 4 | 4 | 5 | 2017-01-01T00:00:00Z |
| 5 | 1 | 7 | 2017-01-08T00:00:00Z |
| 6 | 8 | 6 | 2017-01-08T00:00:00Z |
| 7 | 2 | 5 | 2017-01-08T00:00:00Z |
| 8 | 3 | 4 | 2017-01-08T00:00:00Z |
| 9 | 1 | 6 | 2017-01-15T00:00:00Z |
| 10 | 7 | 5 | 2017-01-15T00:00:00Z |
| 11 | 8 | 4 | 2017-01-15T00:00:00Z |
| 12 | 2 | 3 | 2017-01-15T00:00:00Z |
| 13 | 1 | 5 | 2017-01-22T00:00:00Z |
| 14 | 6 | 4 | 2017-01-22T00:00:00Z |
| 15 | 7 | 3 | 2017-01-22T00:00:00Z |
| 16 | 8 | 2 | 2017-01-22T00:00:00Z |
| 17 | 1 | 4 | 2017-01-29T00:00:00Z |
| 18 | 5 | 3 | 2017-01-29T00:00:00Z |
| 19 | 6 | 2 | 2017-01-29T00:00:00Z |
| 20 | 7 | 8 | 2017-01-29T00:00:00Z |
| 21 | 1 | 3 | 2017-02-05T00:00:00Z |
| 22 | 4 | 2 | 2017-02-05T00:00:00Z |
| 23 | 5 | 8 | 2017-02-05T00:00:00Z |
| 24 | 6 | 7 | 2017-02-05T00:00:00Z |
| 25 | 1 | 2 | 2017-02-12T00:00:00Z |
| 26 | 3 | 8 | 2017-02-12T00:00:00Z |
| 27 | 4 | 7 | 2017-02-12T00:00:00Z |
| 28 | 5 | 6 | 2017-02-12T00:00:00Z |
| 29 | 8 | 1 | 2017-02-19T00:00:00Z |
| 30 | 7 | 2 | 2017-02-19T00:00:00Z |
| 31 | 6 | 3 | 2017-02-19T00:00:00Z |
| 32 | 5 | 4 | 2017-02-19T00:00:00Z |
| 33 | 7 | 1 | 2017-02-26T00:00:00Z |
| 34 | 6 | 8 | 2017-02-26T00:00:00Z |
| 35 | 5 | 2 | 2017-02-26T00:00:00Z |
| 36 | 4 | 3 | 2017-02-26T00:00:00Z |
| 37 | 6 | 1 | 2017-03-05T00:00:00Z |
| 38 | 5 | 7 | 2017-03-05T00:00:00Z |
| 39 | 4 | 8 | 2017-03-05T00:00:00Z |
| 40 | 3 | 2 | 2017-03-05T00:00:00Z |
| 41 | 5 | 1 | 2017-03-12T00:00:00Z |
| 42 | 4 | 6 | 2017-03-12T00:00:00Z |
| 43 | 3 | 7 | 2017-03-12T00:00:00Z |
| 44 | 2 | 8 | 2017-03-12T00:00:00Z |
| 45 | 4 | 1 | 2017-03-19T00:00:00Z |
| 46 | 3 | 5 | 2017-03-19T00:00:00Z |
| 47 | 2 | 6 | 2017-03-19T00:00:00Z |
| 48 | 8 | 7 | 2017-03-19T00:00:00Z |
| 49 | 3 | 1 | 2017-03-26T00:00:00Z |
| 50 | 2 | 4 | 2017-03-26T00:00:00Z |
| 51 | 8 | 5 | 2017-03-26T00:00:00Z |
| 52 | 7 | 6 | 2017-03-26T00:00:00Z |
| 53 | 2 | 1 | 2017-04-02T00:00:00Z |
| 54 | 8 | 3 | 2017-04-02T00:00:00Z |
| 55 | 7 | 4 | 2017-04-02T00:00:00Z |
| 56 | 6 | 5 | 2017-04-02T00:00:00Z |
答案 2 :(得分:0)
尝试此程序。逻辑基于循环法
请注意,我使用了:周而不是日期。安排特定日期的比赛需要有关每天多少的其他信息,你是否可以让一支球队每周比赛多次,等等。
该过程的输入是逗号分隔的团队列表。如果输入奇数,则会创建“DUMMY”以使循环工作。这不会插入表中,但会提示您计划。您可以使用insert语句替换DBMS_OUTPUT
语句
create or replace
procedure test_schedule(p_teams in varchar2)
is
type t_teams is table of varchar2(15);
cursor c_teams is
select trim(regexp_substr(p_teams,'[^,]+', 1, level)) team
from dual
connect by regexp_substr(p_teams, '[^,]+', 1, level) is not null;
v_teams t_teams := t_teams();
v_team_shift varchar2(60);
v_weeks number;
v_count number:=0;
v_date date;
begin
for r_teams in c_teams loop
v_count := v_count + 1;
v_teams.extend();
v_teams(v_count) := r_teams.team;
end loop;
if mod(v_count, 2) != 0 then
v_count := v_count + 1;
v_teams.extend();
v_teams(v_count) := 'DUMMAY';
end if;
for i in 1..v_count loop
dbms_output.put_line(v_teams(i));
end loop;
v_weeks := v_count - 1;
dbms_output.put_line('Weeks: '|| v_weeks||' Count: '||v_count);
for week in 1..v_weeks loop
for i in 1..v_count/2 loop
dbms_output.put_line(week||': '||v_teams(i)||' X '||v_teams(v_count-i+1));
dbms_output.put_line(week+v_weeks||': '||v_teams(v_count-i+1)||' X '||v_teams(i));
end loop;
-- shift teams
v_team_shift := v_teams(v_count);
for i in 1..v_count-2 loop
v_teams(v_count-i+1) := v_teams(v_count-i);
end loop;
v_teams(2) := v_team_shift;
end loop;
end;
/
为了测试,我使用了:
begin test_schedule('TEAM A, TEAM B, TEAM C, TEAM D, TEAM E'); end;
/
输出:
Week Home Away
1: TEAM A X DUMMAY
6: DUMMAY X TEAM A
1: TEAM B X TEAM E
6: TEAM E X TEAM B
1: TEAM C X TEAM D
6: TEAM D X TEAM C
2: TEAM A X TEAM E
7: TEAM E X TEAM A
2: DUMMAY X TEAM D
7: TEAM D X DUMMAY
2: TEAM B X TEAM C
7: TEAM C X TEAM B
3: TEAM A X TEAM D
8: TEAM D X TEAM A
3: TEAM E X TEAM C
8: TEAM C X TEAM E
3: DUMMAY X TEAM B
8: TEAM B X DUMMAY
4: TEAM A X TEAM C
9: TEAM C X TEAM A
4: TEAM D X TEAM B
9: TEAM B X TEAM D
4: TEAM E X DUMMAY
9: DUMMAY X TEAM E
5: TEAM A X TEAM B
10: TEAM B X TEAM A
5: TEAM C X DUMMAY
10: DUMMAY X TEAM C
5: TEAM D X TEAM E
10: TEAM E X TEAM D