我正在尝试编写一个 MySQL 查询,该查询将连续三个表连接到主表,但是根据最后一个正在连接的表上的值有条件地执行此操作。我尝试这样做的两种方法都有问题:
- 要么没有显示我需要的所有主要行
- 或者我在那里得到一些额外的不相关行。
表结构是现有系统的一部分,我无法更改它。此外,一旦我弄清楚 SQL,我将不得不找到一种将其与其查询系统集成的方法,因此 SQL 越简单越好!
我将在这里放很多细节,抱歉,这篇文章太长了,但我认为最好包含所有信息。
这里有更多信息:
数据模型:
有用户、课程和一个中间内容类型,它存储每个用户在特定课程上的用户信息,称为 cui。我需要查看所有用户的列表,如果有该用户和课程的 cui,也需要包含它。
在数据库中,cui 的字段内容存储在单独的表中,并通过 cui_id 连接,这是麻烦的一部分。
精简的数据库结构:
- 主表:用户(字段:uid、name)
- 崔表:节点(字段:cui_id)
- 用户字段表(字段:cui_id、uid)
- 课程字段表(字段:cui_id、course_id)
加入
user user_field node course_field
---- ---------- ------- ------------
uid ==== uid
name cui_id =========== cui_id ===== cui_id
course_id = 202
尝试查询:
以下查询在具有以下用户的小样本数据集上运行:
- 用户二:查询的课程有cui,其他课程有cui。
- 用户一:对其他课程有 cuis,但对所查询的课程没有。
- 用户六:没有cuis。
第一个查询是对最后一个表的条件连接,问题是它为用户二包含了一个额外的行,这不是正确的 cui。我不想 GROUP BY,因为我认为它不一定会给我正确的行。
SELECT user.uid, user.name, field_user.cui_id,
field_course.course_id
FROM user
LEFT JOIN field_user
ON
user.uid = field_user.uid
LEFT JOIN node AS cui
ON
cui.id = field_user.cui_id
LEFT JOIN field_course
ON
field_course.cui_id = cui.id
AND
field_course.course_id = 202
结果:
uid name cui_id course_id
---------------------------------------------
4 User One 772 NULL
5 User Two 434 202
5 User Two 771 NULL
35 User Six NULL NULL
另一种方法是:
SELECT user.uid, user.name, field_user.cui_id,
field_course.course_id
FROM user
LEFT JOIN field_user
ON
user.uid = field_user.uid
LEFT JOIN node AS cui
ON
cui.id = field_user.cui_id
LEFT JOIN field_course
ON
field_course.cui_id = cui.id
WHERE (
field_course.course_id = 202 OR ISNULL(field_course.course_id))
结果:
uid name cui_nid course_nid
---------------------------------------------
5 User Two 434 202
35 User Six NULL NULL
那个问题是它忽略了用户一,因为用户一确实有其他的cuis,只是不适合正确的课程。
所以问题是,我如何得到这个?
uid name cui_id course_id
--------------------------------------------
4 User One 772 NULL
5 User Two 434 202
35 User Six NULL NULL