繁体   English   中英

使用LEFT JOIN的mySQL SELECT,返回值或在右表中指定NULL WHERE列

[英]mySQL SELECT using LEFT JOIN, returning value or NULL WHERE column is specified in right table

我是一名刚接触php | mySQL的高中老师,我正在尝试开发一个查询来显示我的学生的考试成绩。 挑战是在给定测试中显示分数,如果尚未发布分数则显示NULL。 我想在单个查询中执行两个步骤:

  1. 根据提交的测试结果创建特定课程的学生列表。
  2. 显示每个学生在该测试中的分数,或者,如果由于未进行测试而不存在分数,则在其旁边显示其名称和NULL。

带有每个评估记录的“测试”表包含以下列:

test_id
assessment_id
username
score
maxScore
stopTime

包含每个学生记录的“用户”表包含以下列:

user_id
schoolId
username
first_name
last_name
section

期望的结果:

username | last_name | first_name | schoolId | assessment_id | score | maxScore
------------------------------------------------------------------------------------
jadams1  | Adams     | Joe        | 111111   | 23            | 9     | 12
sbenson1 | Benson    | Sally      | 222222   | 23            | 10    | 12
csmith2  | Smith     | Charlie    | 555555   | NULL          | NULL  | NULL (hasn't taken quiz yet)
dthomp1  | Thompson  | David      | 666666   | 23            | 9     | 12

到目前为止,我已经尝试了很多东西。 第一个是基本的LEFT JOIN。 这会为每个学生生成一行,但由于我为“tests.assessment_id”指定了一个值,因此它不会为尚未参加测验的学生显示行。 我希望它显示测验结果(如果存在),如果学生没有参加测验则显示包含NULL分数值的行。

SELECT
  users.last_name,
  users.first_name,
  tests.score,
  tests.maxScore
FROM users
  LEFT JOIN tests
    ON tests.username = users.username
WHERE tests.assessment_id = '23'
    AND users.section = 'S432-01'

以上产生:

username | last_name | first_name | schoolId | assessment_id | score | maxScore
------------------------------------------------------------------------------
jadams1  | Adams     | Joe        | 111111   | 23            | 9     | 12
sbenson1 | Benson    | Sally      | 222222   | 23            | 10    | 12
dthomp1  | Thompson  | David      | 666666   | 23            | 9     | 12

以下是最近的迭代。 它为练习测验生成一个NULL行(没有分配assessment_id)以及真实的一行。 在最终报告中,为每个学生只创建一行非常重要,但不要错过任何学生:

SELECT DISTINCT
  users.username,
  users.last_name,
  users.first_name,
  users.schoolId,
  if(tests.assessment_id ='23','23','') AS assessment,
  if(tests.assessment_id ='23',tests.score,'') AS score,
  if(tests.assessment_id ='23',tests.maxScore,'') AS maxScore
FROM `users`
  LEFT JOIN tests
    ON tests.username = users.username
WHERE users.section = 'S432-01'
    AND (tests.assessment_id = '23'
      OR tests.assessment_id IS NULL)
ORDER BY users.last_name,users.first_name,tests.assessment_id

以上产生:

username | last_name | first_name | schoolId  | assessment_id | score | maxScore
------------------------------------------------------------------------------------
jadams1  | Adams     | Joe        | 111111    | NULL          | NULL  | NULL
jadams1  | Adams     | Joe        | 111111    | 23            | 9     | 12
sbenson1 | Benson    | Sally      | 222222    | NULL          | NULL  | NULL
sbenson1 | Benson    | Sally      | 222222    | 23            | 10    | 12
csmith2  | Smith     | Charlie    | 555555    | NULL          | NULL. | NULL (hasn't taken quiz yet)
dthomp1  | Thompson  | David      | 666666    | NULL          | NULL. | NULL
dthomp1  | Thompson  | David      | 666666    | 23            | 9     | 12

任何想法如何在单个查询中使这个工作? 我认为我遇到了性能问题,所以我希望尽可能保持简单。

谢谢你的帮助! -克里斯

这会工作,

SELECT  users.last_name,
        users.first_name,
        tests.score,
        tests.maxScore
FROM    users
        LEFT JOIN tests
              ON tests.username = users.username AND 
                 tests.assessment_id = '23'
WHERE   users.section = 'S432-01'

您没有从users表中获取所有记录的原因是因为您已过滤了等于23 assessment_id ,其中删除了所有null值( 未评估的学生在此列上具有空值 )。 要获取所有值,请在ON子句上移动tests.assessment_id='23'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM