【问题标题】:MySQL LEFT JOIN Count column Join 3 tablesMySQL LEFT JOIN Count column Join 3表
【发布时间】:2016-12-16 08:21:29
【问题描述】:

我有 3 个表,它们是我的数据库的一部分。

debates (id 'PK', unit_id, starter_pack_id 'FK', title)

debate_stakeholders (id 'PK', starter_pack_id 'FK', name)

debate_groups (id 'PK', debate_id 'FK', student_id, stakeholder_id 'FK')

为此,所有辩论共享相同的利益相关者(总共 4 个利益相关者,所有这些利益相关者都被引用用于所有辩论)。

我预期结果的目的是查询所有辩论,即显示debates.id, debates.title, debate_stakeholders.name, and the Count of how many of those stakeholders occur within that particular debate与相关利益相关者相关,无论利益相关者的数量是否为 0。这部分很重要,因为当我执行其他查询时,我需要知道哪些查询计数大于或等于 1、0 和 null。

这是我的数据库的示例数据:

我的预期结果:(计数只是为了显示它的样子)

我已尝试创建此 MySQL 查询,但无法达到我的确切要求。

我尝试过查询,例如 SELECT a.id, a.name, a.abbreviation, d.id AS debateId, IF(COUNT(b.stakeholder_id) = 0, 0, COUNT(b.stakeholder_id)) AS total_freq FROM debate_stakeholders a LEFT JOIN debate_groups b ON b.stakeholder_id = a.id LEFT JOIN debates as d ON b.debate_id = d.id GROUP BY a.id, b.debate_id,d.id HAVING
COUNT(*) < 3 ORDER BY a.id,d.id LIMIT 1

但这还没有完全计划好。

【问题讨论】:

  • 到目前为止你尝试过什么?你应该包括这个,一些示例数据会更好。
  • 那么辩论表有两个唯一的键? id 还有starter_pack_id?这是为什么呢?
  • @ThorstenKettner 为什么在LEFT JOIN 中过滤掉记录?看看here.
  • 因为debates.starter_pack_id 是另一个表的外键,但与此解决方案无关。事实上,我不应该包括它。我会删除它
  • 啊,好吧。您将其标记为“PK”。

标签: mysql join left-join


【解决方案1】:

试试这个,希望对你有帮助:

SELECT d.id, COALESCE(d.title, 'NA') AS title, COALESCE(ds.name, 'NA') AS name, COUNT(ds.id) AS count
FROM debates d
LEFT JOIN debate_groups AS dg ON d.id = dg.debate_id
LEFT JOIN debate_stakeholders AS ds ON dg.stakeholder_id = ds.id
GROUP BY d.id, dg.stakeholder_id

【讨论】:

  • 不。您过滤掉了一些版主。 OP 希望每位主持人都出席每场辩论。
  • 我更希望每一位利益相关者都出席每场辩论,无论计数是否为 0
【解决方案2】:

我必须承认表名让我感到困惑。 辩论__stakeholder 与辩论无关。它是属于入门包的利益相关者,也有属于入门包的辩论。至少这是我从表结构中读到的。然后一个辩论_小组由一个学生和一个辩论中的利益相关者组成。将其称为一个组很奇怪。

但是,您似乎希望将所有利益相关者与所有辩论结合在一个初学者包中(即获取所有组合)。然后你想计算有多少学生与每个这样的辩论/利益相关者组合相关。因此,编写一个查询来计算每个辩论和利益相关者的学生数(按辩论和利益相关者分组的聚合查询),并将其用作您外部加入辩论/利益相关者组合的子查询。

SELECT d.id,
       d.title,
       ds.name,
       COALESCE(dg.students, 0) AS "count"
FROM debates d
JOIN debate_stakeholders ds
    ON ds.starter_pack_id = d.starter_pack_id
LEFT JOIN
(
    SELECT debate_id, stakeholder_id, COUNT(*) AS students
    FROM debate_groups
    GROUP BY debate_id, stakeholder_id
) dg
    ON dg.debate_id = d.id AND
       dg.stakeholder_id = ds.id;

演示在这里:

SQLFiddle

【讨论】:

  • 你是冠军。这似乎完成了我想要实现的目标。谢谢大佬
  • @Tim Biegeleisen:谢谢。
  • 可以添加一个吗?如果我想使用那个精确值,但只显示计数小于“3”或实例的记录怎么办?但仍显示其他 null 或 0 计数记录
  • 在末尾添加WHERE COALESCE(dg.students, 0) &lt; 3
猜你喜欢
  • 1970-01-01
  • 2013-04-19
  • 2020-05-17
  • 2021-11-06
  • 1970-01-01
  • 2019-07-21
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
相关资源
最近更新 更多