我是SQL
的新手,我試圖製作一張存儲足球聯賽時間表的表格。該表包含4列(matchID, home_team, away_team, match_date
)。我有8支不同的球隊,每支球隊都應該對陣其他兩支球隊。比賽將持續14周(每週4場比賽)。我搜索並發現double round robin algorithm
做同樣的事情,但我不知道如何寫在PL/SQL中,並生成一個表。請幫幫我。在PL/SQL中實現雙循環算法
回答
的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
| 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 |
您可以使用此查詢爲您的表生成記錄。請注意,我沒有執行任何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
腳本並輸入正確的日期。
感謝您的支持。該表已成功創建。但我有一個問題,根據循環賽算法,球隊不能進行第二場比賽,直到所有其他球隊都進行了第一場比賽。這就是爲什麼我想每週需要4場比賽,以便所有8支球隊都能完成他們的第一場比賽。看看這個http://tournamentscheduler.net/schedule/NDg2NDg0MzUzNg。 –
如果它是一次性活動,您可以從excel生成更新腳本以將其更新爲正確的日期。例如:'update table SET matchdate =
是的,這很容易,但很耗時。有沒有辦法創建一個過程?如果一週內所有4場比賽的match_date保持不變,所有4場比賽都在同一天舉行,我想這會更容易。因此,每個球隊都會在一週後進行比賽。 –
試試這個程序。邏輯基於循環法
請注意,我使用:周而不是日期。安排特定日期的比賽需要其他信息,例如每天有多少,你每週可以有多少次比賽,等等。
該過程的輸入是逗號分隔的隊列表。如果輸入奇數,則會創建一個「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
- 1. 循環算法實現Java
- 2. 如何在Elixir中實現雙循環?
- 3. PLSQL中循環
- 4. 在C++中實現在無向圖算法中尋找循環
- 5. PLSQL和循環
- 6. 雙循環鏈接列表實現
- 7. 我如何在Objective-C中實現Mid-Point/Bresenham循環算法?
- 8. 角算法:停止ngFileUpload雙循環?
- 9. 循環法java實現
- 10. 實現循環
- 11. JavaScript中的數學運算並在循環中實現它?
- 12. PLSQL循環提交更新
- 13. oracle plsql動態循環
- 14. PLSQL循環層次結構
- 15. PHP循環實現
- 16. 如何實現循環,並計算在PHP中值
- 17. 在RenderScript中實現算法
- 18. Floyd的循環檢測算法的實現是否不正確?
- 19. 在雙循環中回調
- 20. 在plsql程序中無法找出循環的光標
- 21. 如何在循環中創建循環(雙循環)
- 22. 在visualbasic6中實現循環隊列
- 23. 在球拍中實現for循環
- 24. 在圖像中實現降序循環?
- 25. 在open cv中實現For循環?
- 26. 如何實現while循環在xslt中
- 27. 在matlab中實現「不等於」循環
- 28. while循環在Java中的BlockingQueue實現
- 29. 在解釋器中實現Brainfuck循環
- 30. 在simulink模型中實現'for'循環
它看起來像有很多來自這個問題缺少。例如,是否有規定團隊預期在特定時間段內參加的頻率,主客場比賽是否允許順序進行,所有比賽的實際時間表是什麼(以及其他許多我確定的比賽) –
請參閱https://stackoverflow.com/questions/13372232/sql-all-possible-round-robin-combinations-between-two-tables –