2017-06-20 213 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