MySQL LEFT JOIN问题:检索A列中的研讨会名称和B列中的行ID

时间:2014-02-23 16:51:18

标签: mysql sql

为垃圾问题标题道歉,但将我的要求概括为一行是有点棘手的。我通常没有MySQL JOIN的问题,但是这个问题让我感到厌烦。

我正在建立一个培训反馈系统,并且一个功能想要显示数据库中所有可用研讨会的列表,已分配给定代表的研讨会以及该代表是否已为这些研讨会提交任何反馈指定的研讨会。

我可以在几个查询中执行此操作,但我尝试使用单个查询做一些更优雅的事情。

我的数据库结构的相关细节:

WORKSHOPS

  • id:INT
  • 名称:TINYTEXT

DELEGATES

  • id:INT
  • 名称:TINYTEXT

FEEDBACK

  • delegate_id:INT
  • workshop_id:INT
  • 反馈:TEXT

DELEGATES_X_WORKSHOPS

  • delegate_id:INT
  • workshop_id:INT
表中的

delegate_id workshop_id DELEGATESWORKSHOPS表的外键。

由于任何给定的代表都可以分配到多个研讨会,我使用DELEGATES_X_WORKSHOPS表作为交叉引用表,这样我就可以快速搜索分配给任何给定研讨会的人员或任何给定代表的研讨会分配给。

但是,我尝试了LEFT JOINING几种不同的方式,我无法在左侧获得完整的研讨会列表,并在右侧为匹配的delegate_id匹配(如果存在)。

示例数据 代表 Ross 有delegate_id = 1 注册研讨会

  • C ++
  • PHP
  • ASP.NET
  • HTML5
  • 的JavaScript

Ross被分配到PHP,HTML5和JavaScript

问题1是:如何为delegate_id = 1返回以下内容:

[workshop] | [assigned]
C++        | null
PHP        | TRUE
ASP.NET    | null
HTML5      | TRUE
JavaScript | TRUE

(现在关于B列的内容并不重要,如果没有将特定的delegate_id分配给研讨会,我只想要一个null。)

我用过这个:

SELECT
  workshops.name,
  delegates_x_workshops.delegate_id
FROM
  workshops
LEFT JOIN
  delegates_x_workshops
ON
  workshops.id=delegates_x_workshops.workshop_id
WHERE
  delegates_x_workshops.delegate_id=1

但是我只返回delegate_id = 1的3行,而不是所有研讨会的5行。

问题2涉及更多: 以问题1为基础,如果反馈留给罗斯分配到的研讨会,我将如何使用C栏显示?

[workshop] | [assigned] | [givenfeedback]
C++        | null       | null
PHP        | TRUE       | TRUE
ASP.NET    | null       | null
HTML5      | TRUE       | null
JavaScript | TRUE       | TRUE

提前感谢任何能够做到这一点的人,并且知道我正在喋喋不休。正如我所说,我可以通过几个不同的查询来解决这个问题,但我正在努力保持优雅。

毫无疑问,其中一半需要澄清,所以提出任何问题。

由于

2 个答案:

答案 0 :(得分:0)

对于问题1,您需要将where条件移动到on子句中。它将left outer join转换为inner join,因为不匹配的行具有NULL值:

SELECT w.name, dxw.delegate_id
FROM workshops w LEFT JOIN
     delegates_x_workshops dxw
     ON w.id = dxw.workshop_id and
        dxw.delegate_id = 1;

对于第二个问题,我认为这就是你想要的:

SELECT w.name,
       (case when max(w.name = 'Ross') > 0 then 'True' end) as Assigned,
       (case when count(f.workshop_id) > 0 then 'True' end) as Feedback
FROM workshops w LEFT JOIN
     delegates_x_workshops dxw
     ON w.id = dxw.workshop_id and
        dxw.delegate_id = 1 LEFT JOIN
     delegates d
     on d.id = dxw.delegate_id LEFT JOIN
     feedback f
     on f.workshop_id = w.id
GROUP BY w.name;

答案 1 :(得分:0)

供参考,这是我的最终查询:

SELECT DISTINCT
  workshops.id AS wid,
  workshops.name AS workshop,
  (delegates_x_workshops.delegate_id IS NOT NULL) AS assigned,
  (initial_feedback.delegate_id IS NOT NULL
   OR
   ongoing_feedback.delegate_id IS NOT NULL) AS hasfeedback
FROM
  workshops
LEFT JOIN
  delegates_x_workshops
ON
  workshops.id = delegates_x_workshops.workshop_id
AND
  delegates_x_workshops.delegate_id = 1
LEFT JOIN
  initial_feedback
ON
  workshops.id = initial_feedback.workshop_id
AND
  initial_feedback.delegate_id = 1
LEFT JOIN
  ongoing_feedback
ON
  workshops.id = ongoing_feedback.workshop_id
AND
  ongoing_feedback.delegate_id = 1
ORDER BY
  workshop ASC

对于WORKSHOPS表中的每个研讨会,我将获得研讨会的ID和名称,如果分配了给定的delegate_id,则为1或0,如果是任何类型的反馈,则为1或0(我有2种已经离开了那个研讨会。

可怕地认为我遗失的所有内容都是AND上的LEFT JOIN条件。

再次感谢戈登!