2013-09-22 3 views
0

У меня вопрос в задании, которое я потратил более 40 часов, пытаясь решить. Я получаю правильный ответ, когда присоединяюсь к двум таблицам вместе, но когда я добавляю третий, я теряю строку, а счет неверен.SQL-запрос из 3 таблиц, возвращающих неверные результаты

Это находит правильный ответ:

use prime_minister_2013; 
select ministry.pm_name, count(*) AS Number_times_PM, ministry.min_begin, ministry.party,deputy_pm.deputy_name 
from ministry, deputy_pm 
where deputy_pm.min_nr = ministry.min_nr 
and ministry.party <> 'ALP' 
and min_begin < '1930-01-01' 
group by ministry.pm_name; 

, но когда я пытаюсь добавить третью таблицу, содержащую который был генерал-губернатором, когда они избраны теряет один из рядов (ПМ) и рассчитывать на 2 строки удваиваются.

Я предполагаю, что у меня есть соединения/& или группировка неправильная!

use prime_minister_2013; 
select ministry.pm_name, count(*) AS Number_times_PM, ministry.min_begin, ministry.party,deputy_pm.deputy_name, gg_title, gg_name 
from ministry 
join deputy_pm 
on deputy_pm.min_nr = ministry.min_nr 
join governor_general 
on governor_general.pm_name = ministry.pm_name 
and ministry.party <> 'ALP' 
and min_begin < '1930-01-01' 
group by ministry.pm_name; 

Любое предложение с благодарностью - за счет 25/9/13


Спасибо всем за ваши комментарии - пожалуйста, найти образцы таблиц ниже:

Таблица: Министерство

min_nr pm_name party min _begin 
1 Barton E Protectionist 1/01/1901 
15 Bruce S M Nationalist 9/02/1923 
27 Chifley J B ALP 13/07/1945 
28 Chifley J B ALP 1/11/1946 
9 Cook J Liberal 24/06/1913 
24 Curtin J J A ALP 7/10/1941 
25 Curtin J J A ALP 21/09/1943 

Таблица: заместитель PM

min_nr deputy _ name party 
1 Deakin A Protectionist 
2 Lyne W J Protectionist 
3 Hughes W M ALP 
4 McLean A Protectionist 
5 Isaacs I A Protectionist 
6 Hughes W M ALP 
7 Cook J Free Trade 
8 Hughes W M ALP 
9 Forrest J Liberal 

Таблица: Губернатор генералами

GG_name GG_title GG _begin GG _end pm_name 
Hope J A L 7th Earl of Hopetoun 1/01/1901 9/01/1903 Barton E 
Tennyson H 2nd Baron Tennyson 9/01/1903 21/01/1904 Barton E 
Northcote H S Baron Northcote 21/01/1904 9/09/1908 Deakin A 
Ward W H 2nd Earl of Dudley 9/09/1908 31/07/1911 Deakin A 
Denman T 3rd Baron Denman 31/07/1911 18/05/1914 Fisher A 
Munro Ferguson, R C Rt Hon Sir 18/05/1914 6/10/1920 Cook J 
Forster H W Baron Forster 6/10/1920 8/10/1925 Hughes W M 
Baird J L Baron Stonehaven 8/10/1925 22/01/1931 Bruce S M 
Isaacs I A Rt Hon Sir 22/01/1931 23/01/1936 Scullin J H 
Hore-Ruthven A G A Brig. Gen, Baron Gowrie 23/01/1936 30/01/1945 Lyons J A 
Gloucester H W F A HRH Prince, Duke of Gloucester 30/01/1945 11/03/1947 Curtin J J A 

В ответ на предложения Space Dogs - я попытался это:

use prime_minister_2013; 
select ministry.pm_name AS 'PM Name', DATE_FORMAT (ministry.min_begin,'%Y') As 'Ministry Started', ministry.party AS 'Party', deputy_pm.deputy_name AS 'Deputy PM Name', COUNT(DISTINCT ministry.min_begin) AS 'Number of times PM', gg_title AS 'GG Title', gg_name AS 'GG Name' 
from ministry 
join deputy_pm 
on deputy_pm.min_nr = ministry.min_nr 
join governor_general 
on governor_general.pm_name = ministry.pm_name 
and ministry.party <> 'ALP' 
and min_begin < '1930-01-01' 
group by ministry.pm_name; 

Это дало мне:

который получает там, - но до сих пор отсутствует в ПМ, не имеют GG

+0

Как выглядят таблицы/данные? – dcaswell

+0

создать sqlfiddle plz – developerCK

+0

Просьба предоставить образцы данных с желаемым результатом. –

ответ

0

Это трудно помочь, не видя данных, но вы запрашиваете предложения, так вот что я хотел бы сделать.

Прежде всего, проверьте данные - вы говорите, что некоторые строки исчезают, а счетчик - в других двухместных номерах, что означает, что для некоторых PM в данных не было генерала-губернатора, а для других было два. Вы должны попробовать гораздо более простые запросы, просто выбрав несколько элементов (без функции группы или функции COUNT), которые будут объединены в каждую из двух таблиц отдельно, чтобы вы могли понять данные.

Вы делаете INNER JOIN (что JOIN эквивалентно в mysql, IIRC). Таким образом, вы получите только результаты, которые соответствуют с обеих сторон, если есть отсутствующий губернатора, то вы потеряете эту строку, так что одна вещь, чтобы попытаться это LEFT JOIN - попробовать что-то просто: первый

USE prime_minister_2013; 
SELECT ministry.pm_name, gg_name 
FROM ministry 
LEFT JOIN governor_general 
ON governor_general.pm_name = ministry.pm_name ; 

И посмотрите, что это заставляет вас (если в gg_name в пробеле есть пробел, попробуйте еще раз с JOIN, чтобы увидеть, что эта строка исчезает). Вы также увидите, есть ли PM с двумя GG.

Оттуда это зависит от того, какие результаты вы на самом деле пытаетесь получить - чтобы подсчет был правильным, вы можете сделать COUNT(DISTINCT ministry.min_begin) вместо COUNT(*). Первое будет подсчитывать количество отчетных периодов, в течение которых началось министерство (число или время, когда человек был PM), а не количество совпадающих строк.

Есть еще несколько вещей, о которых стоит подумать - в вашем запросе вы группируете только одну строку, тогда вы выбираете другие поля (ministry.min_begin и т. Д.), Которые, если я правильно помню mysql, соответствующий ряд, который может быть не таким, каким вы хотите. Таким образом, вы можете рассмотреть MIN(ministry.min_begin) и т. Д.

Наконец, опять же, это зависит от ваших данных, возможно, данные хранят даты, когда все меняется - например, если PM изменился, но GG остался прежним, вы можете имеют несколько строк PM, но только одну строку GG, которая охватывает все из них (и если это австралийский вопрос, я думаю, что это определенно так). В этом случае вам понадобится сделать JOIN на пересечении дат.

Тем не менее, я думаю, что вам следует начать, вы можете либо обновить этот вопрос, либо если вам нужно попытаться сопоставить даты, вы можете найти другие ответы или задать отдельный вопрос (кстати, этот ответ выглядит многообещающий: MySQL - Finding time overlaps).

Удачи.

EDIT

Я не могу проверить это здесь, но с использованием LEFT JOIN получите обратно свой старый ряд, однако я думаю, что вам нужно быть более умным. Если вам нужен GG для каждого PM, вы не можете присоединиться к таблицам только pm_name (потому что это только имя PM при запуске GG). Это действительно зависит от того, что фактические данные, что вам нужно, одна вещь, чтобы сделать было бы:

USE prime_minister_2013; 
SELECT ministry.pm_name, count(*) AS Number_times_PM, GG_name 
    FROM ministry 
    JOIN deputy_pm 
    ON deputy_pm.min_nr = ministry.min_nr 
    LEFT JOIN governor_general 
    ON governor_general.GG_begin <= min_begin AND governor_general.GG_end >= min_begin 
    AND ministry.party <> 'ALP' 
    AND min_begin < '1930-01-01' 
GROUP by ministry.pm_name, GG_name; 

Но я думаю, что ваши данные намеренно, чтобы быть трудно, так что это действительно зависит от того, что вы пытаетесь найти. Возможно, вам понадобится выполнить два запроса (или один запрос с подзапросом), потому что вам может понадобиться знать PM, у которых было более одного GG под ними в отдельных терминах.

Но если вы играете с вещами выше, вы, вероятно, можете куда-то добраться.

+0

Спасибо вам большое за помощь. Я попытаюсь проработать ваши предложения Space Dog. Я проверил нахождение совпадений времени (спасибо), но мне, вероятно, нужно немного больше направления с этим! очень новые запросы! – user2714655

+0

Если вы можете отредактировать свой вопрос, чтобы опубликовать пример данных в таблицах, мы могли бы помочь вам больше. В идеале, после сужения строк проблем, как я объяснял выше, вы можете просто разместить эти несколько строк, чтобы проиллюстрировать проблему. Трудно дать какой-либо другой совет с информацией, которую мы в настоящее время имеем. И, честно говоря, мне никогда не приходилось выполнять работу с перекрытием времени в mysql раньше, поэтому вам может быть лучше задавать отдельный вопрос по этому вопросу - однако вам может и не нужно это делать, я не может сказать, не видя некоторые данные. – SpaceDog

+0

спасибо. Я попытался добавить примеры таблиц - но он потерял форматирование! Я попробовал ваше предложение, и вы правы, есть некоторые PM без GG в таблицах. В следующий раз я попробовал ваш счет, и теперь он отсортировал счет. Как мне вернуть PM, у которого нет GG? – user2714655

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