2013-06-02 2 views
1

В моем проекте базы данных мне пришлось создать базу данных о некоторых данных Олимпийских игр.SQL: подсчет из той же таблицы/поля, но разные значения

Я должен построить следующий запрос, а также:

Compute медали стола для конкретных Олимпийских игр, поставляемых пользователем. Стол Medal должен содержать код IOC страны, за которым следует количество золотых, серебряных, бронзовых и медалей. Сначала это должно быть , отсортированное по количеству золота, затем серебра и, наконец, бронзы.

В принципе, у меня есть стол Medals, который содержит медали, выигранные некоторыми участниками в какой-либо олимпийской игре.

Медали хранятся следующим образом: «Золотая медаль», «Серебряная медаль», «Бронзовая медаль» в поле color моего стола Medals.

Я пытался использовать следующий запрос:

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 

Ну, это дает мне совершенно фантастический результат. Я знаю, что с этим вопросом что-то не так, но не могу понять, что это такое!

Надеется, что вы можете мне помочь :)

Благодаря

Примечания: Я игнорировал общее количество запросов (как просил в присваивания) на данный момент. Как только я придумал построить первую часть, я попробую на общую сумму

+0

Совершенно странно, каким образом? – gkalpak

+1

Ну, мне уже поздно, но попробуйте добавить 'WHERE q1.country = q2.country AND q1.country = q3.country' непосредственно перед' GROUP BY q1.country'. Он работает лучше? – 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).

Другим решением было бы подключиться к q1, q2 и q3 ON country.

Смежные вопросы