2017-06-20 161 views
0

我有多個表我試圖從單個查詢中獲取數據。我似乎接近一個解決方案,但似乎無法得到我期待的數據結果。是我的表的MySQL多連接查詢

實例如下(字段已被截斷):

表C
ID
名稱
縮寫

表MR(關係表達的關係表C和M一起通過ID)
ID
c.id
m.id

表米
ID

表CNT
ID
c.id

表CMP
ID
cnt.id
活性

我想是從C中的所有字段,來自M的所有字段,其中m.id = c.id,所有活動(活動= 1)來自CMP的id在cnt.id上匹配。

我最近查詢(幾十個迭代之後):

SELECT c.id AS id 
    , c.name AS name 
    , c.abbreviation AS abbr 
    , c.active AS active 
    , c.last_modified AS last_modified 
    , c.modified_by AS modified_by 
    , mr.media_id 
    , mr.related_object_table 
    , mr.related_object_id 
    , m.orig_name AS img_name 
    , m.unique_name AS img_slug 
    , m.file_type AS confed_file_type 
    , m.file_size AS file_size 
    , COUNT('cmp.id') AS comps 
FROM confederations AS c 
LEFT JOIN media_relationships AS mr 
ON mr.related_object_id = c.id 
AND mr.related_object_table = 'confederations' 
LEFT JOIN media AS m 
ON m.id = mr.media_id 
INNER JOIN countries AS cnt 
ON cnt.confederations_id = c.id 
INNER JOIN competitions AS cmp 
ON cmp.countries_id = cnt.id 
AND cmp.active = 1; 

我不精通加盟。基本上,我期望的結果是:對於每個聯邦(表C),我希望聯邦名稱,縮寫,活動狀態(活動),最後修改日期,修改方式;從媒體關係表(表MR),我想要與該聯盟相關聯的圖像ID,以便我可以使用該ID從媒體表(M)中獲取聯合主圖像的圖像名稱和圖像塊。

現在我還想要一個給定聯盟的比賽總數(表CMP)。國家/地區ID與國家/地區表(國家/地區表)中的主要國家/地區ID關聯存儲。表CNT中的每個國家都有一個聯合身份證。因此,爲了獲得每個聯盟的比賽總數,我試圖通過表CNT中的CONFEDERATIONS_ID將所有國家都納入其各自的聯盟中,然後在聯盟中我想從表CMP中選擇所有比賽,並且匹配來自國家編號組的COUNTRIES_ID對於給定的邦聯。 (在這一點上,我認爲我很困惑自己如何得到我想要的)

不知何故,我得到了正確的比賽數,但我得到重複的聯合會作爲結果。比如我我得到一些類似的(假設我有2,1和3場分別比賽3個不同聯合會):

Competitions 1 : name 1 | abbreviation 1 | image 1 | total competitions = 2; 
Competitions 1 : name 1 | abbreviation 1 | image 1 | total competitions = 1; 
Competitions 1 : name 1 | abbreviation 1 | image 1 | total competitions = 3 

我到底做錯了什麼?

+0

嘗試將你的內連接放在你的左連接上,看看它是否有效。 – grepLines

+0

應該「COUNT('cmp.id')」,是「COUNT(cmp.id)」?另外,您想要通過(例如GROUP BY)進行聚合?我不明白你的最後一段。 – Degan

+0

@grepLines:如果我在我的LEFT加入之前放置我的INNER連接,我會得到相同的結果 – user1785997

回答

0

經過反覆試驗,其實我對我自己解決了這個。我回來後我的答案,看看德感的答案,但它是寫比我不同我認爲它非常接近我結束了:

SELECT 
    cnf.id AS confed_id, cnf.name AS confed_name, cnf.abbreviation AS 
    confed_abbr, cnf.active AS confed_active, cnf.modified_by AS 
    confed_mod_by, cnf.last_modified AS confed_last_mod, 
    COUNT(cnt.id) AS total_countries, 
    COUNT(cmp.id) AS total_comps, 
    mr.media_id, mr.related_object_table, mr.related_object_id, 
    mr.primary_img, 
    m.orig_name AS img_name, m.unique_name AS img_slug, m.file_type AS file_type 
FROM confederations AS cnf 
LEFT JOIN media_relationships AS mr 
ON mr.related_object_id = cnf.id AND mr.related_object_table = 'confederations' 
LEFT JOIN media AS m 
ON m.id = mr.media_id 
LEFT JOIN countries AS cnt 
ON cnt.confederations_id = cnf.id AND cnt.active = 1 
LEFT JOIN competitions AS cmp 
ON cmp.countries_id = cnt.id AND cmp.active = 1 
GROUP BY cnf.id 

所以farthis似乎給我結果我可以使用。我不確定,如果我選擇的所有連接的左連接實際上給了我我需要的一切(它會成爲SEEMS),並且在表格變大時是否會省略/添加記錄。如果任何人都可以在我的查詢中指出一個問題,並且我選擇使用左連接而不是像Degan那樣使用左連接和內連接,那會很有幫助。

0

聚合時,你需要分組。

也許這是接近你在找什麼:

SELECT c.id AS id 
    , c.name AS name 
    , c.abbreviation AS abbr 
    , m.orig_name AS img_name 
    , SUM('cmp.id') AS comps 
FROM confederations AS c 
LEFT JOIN media_relationships AS mr 
    ON mr.related_object_id = c.id 
    AND mr.related_object_table = 'confederations' 
LEFT JOIN media AS m 
    ON m.id = mr.media_id 
INNER JOIN countries AS cnt 
    ON cnt.confederations_id = c.id 
INNER JOIN competitions AS cmp 
    ON cmp.countries_id = cnt.id 
    AND cmp.active = 1 
GROUP BY c.id AS id 
     , c.name AS name 
     , c.abbreviation AS abbr 
     , m.orig_name AS img_name 
+0

感謝您發佈此!正如我在上面的回答中所提到的,您在通過Trial和Error獲得可用解決方案之前大約一個小時發佈了消息。我確實使用了Group By,就像你看到的那樣。你能解釋爲什麼你對某些字段有多餘的調用(例如,SELECT FROM聯合會和左聯接media_relationships中的c.id)?你寫MYSQL的方式與我以前見過的不同。 – user1785997

+0

對不起,LEFT JOIN中多餘的選擇條目是我剪切/粘貼時的拼寫錯誤。對困惑感到抱歉。否則,如果沒有設置數據,我只能假設連接是正確的。 – Degan