SQL join仅在所有行匹配时返回结果

时间:2014-09-22 11:49:06

标签: mysql sql sql-server join inner-join

这是我第一次访问网站,所以请保持温柔。我试图在这里找到我的答案,但似乎没有什么能适合这个法案,在阅读了不同类型的连接之后,我仍然没有更聪明。

我有以下表格:

employees (employee_id, name)
assessments (assessment_id, name, pass_score)
authorizations (authorization_id, name)

员工参加登录的评估:

assessments_taken (assessment_taken_id, employee_id, assessment_id, score)

授权由以下各项给出的多项评估组成:

authorization_requirements (auth_req_id, authorization_id, assessment_id)

authorization_id& assessment_id是防止对副本重复的唯一约束。

我试图设计的查询类似于:

SELECT employees.name, authorization.name ...

我只想返回员工和授权,其中员工已通过 authorization_requirements 中给出的授权的所有评估。

任何人都可以帮我找到我要查找的查询/子查询吗?

2 个答案:

答案 0 :(得分:4)

下面的图片可能会帮助您学习SQL连接 - 它甚至可以为您提供一些SQL本身!至于 authorization_requirements ,听起来你需要使用一些WHERE子句和连接。

希望这有帮助,任何澄清,请随时询问!

Sql Join

答案 1 :(得分:0)

看看这个http://sqlfiddle.com/#!2/ac7887/2

我认为此查询会为您完成。它依赖于每个评估每个员工的评估中只有一个条目。如果员工可以多次参加评估并且所有结果都记录在此表中,那么第二个查询应该适合您。

SELECT
  Employees.name Employee,
  authorizations.name Authorization
FROM
  employees
  CROSS JOIN authorizations
  INNER JOIN authorization_requirements ON authorizations.authorization_id = authorization_requirements.authorization_id
  INNER JOIN assessments ON authorization_requirements.assessment_id = assessments.assessment_id
  LEFT JOIN assessments_taken ON employees.employee_id = assessments_taken.employee_id AND assessments.assessment_id = assessments_taken.assessment_id AND assessments.pass_score <= assessments_taken.score
GROUP BY
  Employees.name,
  authorizations.name
HAVING
  COUNT(assessments.assessment_id) = COUNT(assessments_taken.assessment_taken_id)

如果assessment_taken中有多个条目:

SELECT
  Employees.name Employee,
  authorizations.name Authorization
FROM
  employees
  CROSS JOIN authorizations
  INNER JOIN authorization_requirements ON authorizations.authorization_id = authorization_requirements.authorization_id
  INNER JOIN assessments ON authorization_requirements.assessment_id = assessments.assessment_id
  LEFT JOIN (SELECT
               assessments_taken.employee_id,
               assessments_taken.assessment_id,
               MAX(Score) best_score
             FROM
               assessments_taken
             GROUP BY
               assessments_taken.employee_id,
               assessments_taken.assessment_id
             ) best_assessments_taken ON employees.employee_id = best_assessments_taken.employee_id AND assessments.assessment_id = best_assessments_taken.assessment_id AND assessments.pass_score <= best_assessments_taken.best_score
GROUP BY
  Employees.name,
  authorizations.name
HAVING
  COUNT(assessments.assessment_id) = COUNT(best_assessments_taken.assessment_id)

这些查询获取每个员工和授权,然后确保员工在assessment_taken中有一个条目超过了authorization_requirements中指定的每个评估所需的分数

如果不支持CROSS JOIN,您可能需要将这两个表放在子查询中,然后更改连接条件以引用子查询中的列:

SELECT
  employee_authorizations.employee_name Employee,
  employee_authorizations.authorization_name Authorization
FROM
  (SELECT
        employees.employee_id,
        employees.name employee_name,
        authorizations.authorization_id,
        authorizations.name authorization_name
  FROM
        employees,
        authorizations) employee_authorizations
  INNER JOIN authorization_requirements ON employee_authorizations.authorization_id = authorization_requirements.authorization_id
  INNER JOIN assessments ON authorization_requirements.assessment_id = assessments.assessment_id
  LEFT JOIN (SELECT
               assessments_taken.employee_id,
               assessments_taken.assessment_id,
               MAX(Score) best_score
             FROM
               assessments_taken
             GROUP BY
               assessments_taken.employee_id,
               assessments_taken.assessment_id
             ) best_assessments_taken ON employee_authorizations.employee_id = best_assessments_taken.employee_id AND assessments.assessment_id = best_assessments_taken.assessment_id AND assessments.pass_score <= best_assessments_taken.best_score
GROUP BY
  employee_authorizations.employee_name,
  employee_authorizations.authorization_name
HAVING
  COUNT(assessments.assessment_id) = COUNT(best_assessments_taken.assessment_id)