2016-03-01 50 views
-1

我正在製作棒球聯賽桌。比方說,我有以下2個數據庫表:MySQL - 2個外鍵

ID | NAME 
--------------------------- 
1 | Phillies 
2 | Yankees 
3 | Red Sox 

遊戲

ID | TEAM1_ID | TEAM2_ID | TEAM1_SCORE | TEAM2_SCORE 
---------------------------------------------------- 
1 | 2  | 1  | 12   | 8 
2 | 3  | 2  | 9   | 14 
3 | 1  | 2  | 10   | 5 

我想MySQL的給我所有的車隊和他們的結果列表。這包括玩過的所有遊戲,贏得和丟失的遊戲。

有誰知道如何做到這一點?

例如,結果集可能看起來像這樣:

team_name | total_played | total_won | total_lost 
------------------------------------------------- 
Phillies | 2   | 1   | 1 
Yankees | 3   | 2   | 1 
Red Sox | 1   | 0   | 1 

謝謝!

+1

你嘗試過什麼先內的結果嗎?請閱讀[** How-to-Ask **](http://stackoverflow.com/help/how-to-ask) \t \t這裏是[** START **](http ://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/),瞭解如何提高您的問題質量並獲得更好的答案。 –

回答

1

這可能與sgeddes解決方案相同。
我把條件語句中的子查詢,所以我可以測試

SQL Fiddle Demo

SELECT t.`NAME`, 
     SUM(play) as total, 
     SUM(WON) as games_won, 
     SUM(LOST) as games_lost, 
     SUM(SCORE) as total_score 
FROM (
     SELECT t.`NAME`, 
      IF(g.`TEAM1_ID`IS NULL, 0, 1) as play, 
      CASE WHEN t.`ID` = g.`TEAM1_ID` AND TEAM1_SCORE > TEAM2_SCORE THEN 1 
        WHEN t.`ID` = g.`TEAM2_ID` AND TEAM1_SCORE < TEAM2_SCORE THEN 1 
        ELSE 0 
      END as WON, 
      CASE WHEN t.`ID` = g.`TEAM1_ID` AND TEAM1_SCORE < TEAM2_SCORE THEN 1 
        WHEN t.`ID` = g.`TEAM2_ID` AND TEAM1_SCORE > TEAM2_SCORE THEN 1 
        ELSE 0 
      END as LOST, 
      CASE WHEN t.`ID` = g.`TEAM1_ID` THEN TEAM1_SCORE 
        WHEN t.`ID` = g.`TEAM2_ID` THEN TEAM2_SCORE 
        ELSE 0 
      END as SCORE       
     FROM teams t 
     LEFT JOIN games g 
     ON t.`ID` = g.`TEAM1_ID` 
     OR t.`ID` = g.`TEAM2_ID` 
    ) T 
GROUP BY t.`NAME` 

輸出

|  NAME | total | games_won | games_lost | total_score | 
|----------|-------|-----------|------------|-------------| 
| Phillies |  2 |   1 |   1 |   18 | 
| Red Sox |  1 |   0 |   1 |   9 | 
|  Some |  0 |   0 |   0 |   0 | 
| Yankees |  3 |   2 |   1 |   31 | 
+0

太好了,謝謝!有什麼辦法可以在輸出表中添加額外的補充,以累積所有團隊的分數?例如。團隊費城人將有一個值18(8 + 10).. – elton73

+0

這接近我的解決方案。唯一的問題是如果一個團隊沒有玩過,這將返回一個不正確的總數:http://sqlfiddle.com/#!9/7089b2/1 – sgeddes

+0

@sgeddes你是否在包含'LEFT JOIN' ? –

2

下面是使用conditional aggregation一個選項:

select t.name, 
    count(g.id) total_played, 
    sum(case when (t.id = team1_id and team1_score > team2_score) then 1 
      when (t.id = team2_id and team2_score > team1_score) then 1 
      else 0 
     end) total_won, 
    sum(case when (t.id = team1_id and team1_score < team2_score) then 1 
      when (t.id = team2_id and team2_score < team1_score) then 1 
      else 0 
     end) total_lost 
from teams t 
    left join games g on t.id in (g.team1_id, g.team2_id) 
group by t.name 
+0

在小提琴中運作良好。我會試試這個。 – elton73

0

像這樣的東西應該工作:

select id, name, 
(select count(*) from games where team1_id = id OR team2_id = id) as total_played, 
(select count(*) from games where (team1_id = id and team1_score > team2_score) OR (team2_id = id and team1_score < team2_score)) as total_won, 
(select count(*) from games where (team1_id = id and team1_score < team2_score) OR (team2_id = id and team1_score > team2_score)) as total_lost 
from teams 

Here是SQL小提琴。

+2

將無法​​正常工作..您只查看team1_id,而不是team2_id。 – Yossi

+0

正確。測試過它,但它只查看team1_id列。 – elton73

+0

@ elton73你試過我的查詢嗎?應該適合你。 – Yossi

1

你可以做這樣的事情:

SELECT t.name,count(*) as TotalPlayed, 
     count(case when s.team1_score > s.team2_score then 1 end) as total_won, 
     count(case when s.team2_score > s.team1_score then 1 end) as total_lose 
FROM teams t 
INNER JOIN (
      SELECT Team1_ID,Team1_score,Team2_Score FROM games 
      UNION ALL 
      SELECT Team2_ID,Team2_Score,Team1_Score FROM games) s 
ON(t.id = s.team1_id) 
GROUP BY t.name 

這將基本使遊戲桌更舒適的工作,乘以記錄每隊這樣的計數會很容易,不會有檢查多種條件。

+0

我可以證實這個作品。剛剛刪除了第3行的拼寫錯誤(在「as total_lose」之後應該沒有逗號)。謝謝! – elton73

+0

沒問題,如果它幫助你,會很感激批准:)而且你是對的,修正了錯字。 @ elton73 – Yossi

+1

這個問題是如果一個團隊還沒有發揮,不會出現'TotalPlayed = 0' –