2017-07-03 108 views
-1

我有以下SQL选择:多LEFT JOIN在多个表

SELECT s.*, 
     GROUP_CONCAT(CONCAT_WS(':', m.type, m.id, m.filename) SEPARATOR ',') AS multimedia, 
     GROUP_CONCAT(CONCAT_WS(':', c.id) SEPARATOR ',') AS categories 
FROM sections s 


LEFT JOIN sections_multimedia sm 
    ON s.id = sm.section_id 
LEFT JOIN multimedia m 
    ON sm.multimedia_id = m.id 


LEFT JOIN sections_categories sc 
    ON s.id = sc.section_id 
LEFT JOIN categories c 
    ON sc.category_id = c.id 


WHERE s.id = s.id 
GROUP BY s.id 
ORDER BY s.position, s.id ASC; 

其结果是,本场“类”有正确的价值观,这是(2,3),但遗憾的是多次重复! (结果是:2,2,2,2,2,2,3,3,3,3,3,3)

我的选择有什么问题?

谢谢你的回复!

+1

您的标题说,内部连接,但您的查询使用左加入? – dbajtr

+0

我的错误!我编辑了标题!谢谢! – Nick

+0

你对这个结果做了什么? – Strawberry

回答

3

当寻找来自不同表的汇总信息,您应该总是加入骨料之前:

SELECT 
    s.*, 
    mul.multimedia, 
    cat.categories 
FROM sections s 
LEFT JOIN 
(
    SELECT 
    sm.section_id, 
    GROUP_CONCAT(CONCAT_WS(':', m.type, m.id, m.filename) SEPARATOR ',') AS multimedia 
    FROM sections_multimedia sm 
    JOIN multimedia m ON sm.multimedia_id = m.id 
    GROUP BY sm.section_id 
) mul ON s.id = mul.section_id 
LEFT JOIN 
(
    SELECT 
    sc.section_id, 
    GROUP_CONCAT(CONCAT_WS(':', c.id) SEPARATOR ',') AS categories 
    FROM sections_categories sc 
    JOIN categories c ON sc.category_id = c.id 
    GROUP BY sc.section_id 
) cat ON s.id = cat.section_id; 
+0

这个查询似乎比戈登的答案更好,这也是对的!但是,这是我能做到的最快的查询结果吗?我想要达到的目标是选择所有属于它们的多媒体和类别的“部分”!什么是我可以运行的最快的查询?因为想象一下,如果我将有1.000.000行!谢谢! – Nick

+0

@Nick。 。 。哪种更快取决于许多有关数据的因素以及是否有任何其他过滤。 –

+0

没有额外的过滤和现在,什么是最快的选择方式? – Nick

2

您可以通过使用DISTINCT得到独特的价值观:

SELECT s.*, 
     GROUP_CONCAT(DISTINCT CONCAT_WS(':', m.type, m.id, m.filename) SEPARATOR ',') AS multimedia, 
     GROUP_CONCAT(DISTINCT CONCAT_WS(':', c.id) SEPARATOR ',') AS categories 

这其实是一种变通。您真正的问题是多个连接为结果集中的每一行创建有价值的笛卡尔积。在进行连接之前进行聚合可能会更好,而不是在聚合时删除重复项。

+0

亲爱的戈登,谢谢您的及时回复!我怎样才能在加入之前达成一致? – Nick

+0

哦,我在发布我的答案后阅读。所以戈登和我持有同样的观点:加入之前的聚合:-) –