为垃圾问题标题道歉,但将我的要求概括为一行是有点棘手的。我通常没有MySQL JOIN的问题,但是这个问题让我感到厌烦。
我正在建立一个培训反馈系统,并且一个功能想要显示数据库中所有可用研讨会的列表,已分配给定代表的研讨会以及该代表是否已为这些研讨会提交任何反馈指定的研讨会。
我可以在几个查询中执行此操作,但我尝试使用单个查询做一些更优雅的事情。
我的数据库结构的相关细节:
WORKSHOPS
表
DELEGATES
表
FEEDBACK
表
DELEGATES_X_WORKSHOPS
表
delegate_id 和 workshop_id 是DELEGATES
和WORKSHOPS
表的外键。
由于任何给定的代表都可以分配到多个研讨会,我使用DELEGATES_X_WORKSHOPS
表作为交叉引用表,这样我就可以快速搜索分配给任何给定研讨会的人员或任何给定代表的研讨会分配给。
但是,我尝试了LEFT JOINING几种不同的方式,我无法在左侧获得完整的研讨会列表,并在右侧为匹配的delegate_id匹配(如果存在)。
示例数据 代表 Ross 有delegate_id = 1 注册研讨会
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
提前感谢任何能够做到这一点的人,并且知道我正在喋喋不休。正如我所说,我可以通过几个不同的查询来解决这个问题,但我正在努力保持优雅。
毫无疑问,其中一半需要澄清,所以提出任何问题。
由于
答案 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
条件。
再次感谢戈登!