Mysql 从3个表中选择行

Mysql 从3个表中选择行,mysql,sql,join,multiple-tables,Mysql,Sql,Join,Multiple Tables,我很感激有很多教程和例子来解释连接概念,但是我很难将这些例子应用到我的特定场景中。我希望能得到一些帮助,如果要求不太多的话,请详细说明解决方案中正在发生的事情,以实现预期的结果 3个表:用户、评估、评估日志 使用者 评估 +--------------+------+-----------+-----------+-----------+-----------+-----------+--------------+----------+---------+----------+ | Assess

我很感激有很多教程和例子来解释连接概念,但是我很难将这些例子应用到我的特定场景中。我希望能得到一些帮助,如果要求不太多的话,请详细说明解决方案中正在发生的事情,以实现预期的结果

3个表:用户、评估、评估日志

使用者

评估

+--------------+------+-----------+-----------+-----------+-----------+-----------+--------------+----------+---------+----------+
| AssessmentID | Name | Criteria1 | Criteria2 | Criteria3 | Criteria4 | Criteria5 | RoleRequired | Required | Renewal | Operator |
+--------------+------+-----------+-----------+-----------+-----------+-----------+--------------+----------+---------+----------+
评估日志

+-----------------+------+----------------+------------+--------+-----------+----------+----------+----------+----------+----------+----------+---------+---------------+---------+
| AssessmentLogID | Date | AssessmentName | AssessedBy | UserID | StaffName | Comments | Verdict1 | Verdict2 | Verdict3 | Verdict4 | Verdict5 | Verdict | RenewalPeriod | NextDue |
+-----------------+------+----------------+------------+--------+-----------+----------+----------+----------+----------+----------+----------+---------+---------------+---------+
当用户进行评估时,一个条目进入评估日志。一些评估是必需的(在必填栏中为true或false),其中一些是可选的。RoleRequired列规定了需要评估的用户角色

我想生成一个用户列表和他们尚未通过的评估。评估必须是必需的,并且必需的角色必须与用户角色匹配。评估日志中缺少条目,且“裁决”列中有“通过”表示评估尚未通过

简单地说,我正在寻找一个可以实现以下结果的查询:

+------------------+-----------------+----------------+
| assessments.Name | users.FirstName | users.LastName |
+------------------+-----------------+----------------+
如果需要评估(required等于true),RequiredRole将与users.Role列匹配,并且评估日志中没有任何条目可用于裁决列具有“通过”值的评估

如果需要进一步澄清,请告诉我


提前谢谢

我建议使用左连接

首先,我们生成评估和用户的交叉乘积,其中包含每个用户的角色所需的所有评估

然后,左连接检查这些评估是否通过

SELECT ...
FROM
    users u
    JOIN assessments a ON (a.RoleRequired = u.Role)
    LEFT JOIN assessment_logs al ON (
            al.AssessmentID = a.AssessmentID
        AND al.UserID = u.UserID
        AND al.Verdict='Pass'
    )

WHERE 
        a.required
    AND al.UserID IS NULL

您的属性名称在表之间不一致,尽管我没有看到任何重复的名称,但您这样做可能只是时间问题,所以我建议您解决这个问题

同时,以下是如何动态重命名列以简化联接语法:

SELECT AssessmentName, UserLastName, UserFirstName
  FROM ( SELECT FirstName AS UserFirstName, Lastname AS UserLastName, Role
           FROM users ) u
       NATURAL JOIN
       { SELECT Name AS AssessmentName, RoleRequired AS Role
           FROM assessments
          WHERE Required ) a
       NATURAL JOIN
       ( SELECT AssessmentName
           FROM assessment_logs
          WHERE Verdict = 'Pass' ) l;

这似乎给了我预期的结果-谢谢你!我将更详细地研究左连接。。。即使有你明确的例子和解释,我也在与这个概念作斗争。似乎您已将其他条件链接到左侧联接上—我阅读的示例涉及从一个表中选择行,并从行匹配的第二个表(右侧)返回行。你能解释一下查询的“AND al.UserID=u.UserID”和“AND al.Verdict='Pass'”部分吗?它的工作原理与普通(内部)联接相同,除非在()上找不到与联接条件匹配的行,而是返回一个伪的all NULL行。因此,b.id为NULL的左连接b ON(cond)将返回a中没有与b中的行匹配的行(cond)。知道了?
SELECT AssessmentName, UserLastName, UserFirstName
  FROM ( SELECT FirstName AS UserFirstName, Lastname AS UserLastName, Role
           FROM users ) u
       NATURAL JOIN
       { SELECT Name AS AssessmentName, RoleRequired AS Role
           FROM assessments
          WHERE Required ) a
       NATURAL JOIN
       ( SELECT AssessmentName
           FROM assessment_logs
          WHERE Verdict = 'Pass' ) l;