2013-06-02 105 views
1

在我的數據庫項目中,我必須建立一個關於奧運會數據的數據庫。SQL:從相同的表/字段計數,但數值不同

我必須建立以下查詢,以及:

爲用戶提供特定的奧運會獎牌計算表。獎牌表應包含 國家的國際奧委會代碼,其次是金牌,銀牌,銅牌和總獎牌的數量。首先應該是 ,按黃金數量排序,然後是銀色,最後是青銅色。

基本上,我有一個表Medals,其中包含一些參加者在某些奧運比賽中獲得的獎牌。

獎牌以下列方式儲存:我的牌桌Medalscolor場中的「金牌」,「銀牌」,「銅牌」。

我嘗試使用下面的查詢:

SELECT q1.country, q1.name as "Game", q1.cntG, q2.cntS, q3.cntB FROM 
(
    SELECT c.countryName as country, g.name as name, count(m.idMedal) as cntG 
    FROM Game g 
    INNER JOIN Participant p 
    ON p.fkGame = g.idGame 
    INNER JOIN Country c 
    ON p.fkCountry = c.idCountry 
    INNER JOIN Medals m 
    ON m.fkMedalist = p.idParticipant 
    WHERE 
    g.name = "2012 Summer Olympics" 
    AND m.color like '%Gold%' 
    GROUP BY c.countryName 
    ORDER BY c.countryName, cntG DESC 
) as q1, 
(
    SELECT c.countryName as country, g.name as name, count(m.idMedal) as cntS 
    FROM Game g 
    INNER JOIN Participant p 
    ON p.fkGame = g.idGame 
    INNER JOIN Country c 
    ON p.fkCountry = c.idCountry 
    INNER JOIN Medals m 
    ON m.fkMedalist = p.idParticipant 
    WHERE g.name = "2012 Summer Olympics" 
    AND m.color like '%Silver%' 
    GROUP BY c.countryName 
    ORDER BY c.countryName, cntS DESC 
) as q2, 
(
    SELECT c.countryName as country, g.name as name, count(m.idMedal) as cntB 
    FROM Game g 
    INNER JOIN Participant p 
    ON p.fkGame = g.idGame 
    INNER JOIN Country c 
    ON p.fkCountry = c.idCountry 
    INNER JOIN Medals m 
    ON m.fkMedalist = p.idParticipant 
    WHERE g.name = "2012 Summer Olympics" 
    AND m.color like '%Bronze%' 
    GROUP BY c.countryName 
    ORDER BY c.countryName, cntB DESC 
) as q3 
GROUP BY q1.country 
ORDER BY q1.cntG, q2.cntS, q3.cntB DESC 

那麼,它給了我完全怪異的結果。我知道這個查詢有問題,但無法弄清楚它是什麼!

希望你能幫助我:)

感謝

注:我忽略了查詢的總數量(如assignement要求)的時刻。一旦我想通的建立第一部分我會盡力總

+0

完全奇怪以什麼方式? – gkalpak

+1

嗯,對我來說已經很晚了,但是可以在'GROUP BY q1.country'之前添加'WHERE q1.country = q2.country AND q1.country = q3.c​​ountry'。它會更好嗎? – gkalpak

+0

它似乎沒有以獨立的方式計算計數。仍然顯示了一些計數,但他們是錯誤的(就像美國隊在某場比賽中贏得了2200枚金牌)。我的數據庫中的數據不是問題 –

回答

3

的數據是沒有問題的 - 你有一個隱含的笛卡爾每個Q1,Q2和Q3之間加入一個事實一個問題。嘗試:

SELECT c.countryName as country, 
     count(case m.idMedal when 'Gold medal' then 1 end) as cntG, 
     count(case m.idMedal when 'Silver medal' then 1 end) as cntS, 
     count(case m.idMedal when 'Bronze medal' then 1 end) as cntB 
FROM Game g 
INNER JOIN Participant p ON p.fkGame = g.idGame 
INNER JOIN Country c ON p.fkCountry = c.idCountry 
INNER JOIN Medals m ON m.fkMedalist = p.idParticipant 
WHERE g.name = "2012 Summer Olympics" 
GROUP BY c.countryName 
ORDER BY cntG DESC, cntS DESC, cntB DESC 
+0

我是SUM()技巧的忠實粉絲,因爲它不那麼冗長。 –

+0

哇,我忘了SUM技巧,工作正常以及:) thx –

2

對不起,您的查詢是一個真正的混亂。你不能簡單地以這種方式加入3個子查詢。

但是,你可以有你在一個查詢想要的東西。我給你的僞代碼,並留下你的細節:)

SELECT 
    [countryName], 
    SUM(color like '%Gold%') as total_gold, 
    SUM(color like '%Silver%') as total_silver, 
    SUM(color like '%Bronze%') as total_bronze, 
    COUNT(*) as total 
FROM Medals 
INNER JOIN Participant (...) 
INNER JOIN Country (...) 
INNER JOIN Game (...) 
WHERE (...) 
GROUP BY [countryName] 
ORDER BY total_gold DESC, total_silver DESC, total_bronze DESC; 
1

有很多方法可以解決,甚至提高你的查詢,其中之一是增加

... 
WHERE q1.country = q2.country 
    AND q1.country = q3.country 

(只是GROUP BY q1.country之前)。

另一解決方案是對JOIN Q1,Q2和Q3 ON country