【问题标题】:Multiple LEFT JOIN in multiple tables多个表中的多个 LEFT JOIN
【发布时间】:2017-07-03 10:13:49
【问题描述】:

我有以下 SQL 选择:

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)

我的选择有什么问题?

感谢您的回复!

【问题讨论】:

  • 您的标题说的是内连接,但您的查询使用的是左连接?
  • 我的错!我编辑了标题!谢谢!
  • 你如何处理这个结果?
  • 我把它们放到了一个 php 数组中!

标签: mysql sql database select


【解决方案1】:

当从不同的表中寻找聚合时,你应该总是在加入之前聚合:

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;

【讨论】:

  • 这个查询似乎比戈登的答案更好,这也是正确的!但这是我能做的最快的查询吗?我想要实现的只是选择所有“部分”以及它们所属的所有多媒体和类别!我可以运行的最快查询是什么?因为想象一下,如果我将有 1.000.000 行!谢谢!
  • @尼克。 . .哪个更快取决于您的数据的许多因素以及您是否有任何额外的过滤。
  • 没有额外的过滤和现在这样,最快的选择方法是什么?
  • 您想从所有表中选择所有数据并聚合。您几乎无法加快速度。查询应该没问题。剩下的就是 DBA 的东西(扇区、分区、表空间……?不知道;我不是 MySQL DBA),或者你投资硬件。
【解决方案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

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

【讨论】:

  • 亲爱的戈登,感谢您的及时回复!在加入之前我如何同意?
  • 哦,我在发布答案后阅读了这篇文章。所以 Gordon 和我持有相同的观点:加入前先聚合 :-)
猜你喜欢
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
  • 2013-05-14
相关资源
最近更新 更多