doukunsan5553 2017-04-24 14:04
浏览 133
已采纳

如果值不存在,如何在左连接字段上返回null

I have five(5) tables: students, subjects, period_one, period_two and period_three. I'm performing a left join to select values from these five tables:

Students Table (students)

  student_id    | Name
  --------------|-------
  1             |John
  2             |Peter
  3             |Flomo 

Subjects Table (subjects)

  subject_id       |SubjectName
  -----------------|-------
  math101          |Mathematics
  eng201           |English
  lang303          |Language Arts

Period One Table (period_one)

  id|student_id |subject_id| score
  --------------|----------|-----
  1 |1          | math101  |99
  2 |2          | eng201   |88
  3 |3          | lang303  |77 

Period Two Table (period_two)

  id|student_id |subject_id| score
  --------------|----------|-----
  1 |1          | math101  |100
  2 |2          | eng201   |60
  3 |3          | lang303  |65 

Period Three Table (period_three)

  id|student_id |subject_id| score
  --------------|----------|-----
  1 |1          | math101  |71
  2 |2          | eng201   |51
  3 |3          | lang303  |71

Here is the query I'm using to retrieve records Query1:

SELECT period_one.student_id, period_one.subject_id, period_one.score, period_two.score,period_three.score

from period_one

LEFT JOIN period_two
ON period_one.subject_id = period_two.subject_id
AND period_one.student_id = period_two.student_id

LEFT JOIN period_three 
on period_one.subject_id = period_three.subject_id
AND period_one.student_id = period_three.student_id

WHERE period_one.student_id = 10      

The problem with the code above is if the student id I'm looking for is not in the very first table(periodOne) the left join is being apply to the query returns null even if records of that student are in the others tables(periodTwo and periodThree). I look the issue up(https://www.w3schools.com/sql/sql_join_left.asp) and verified that is was not the best way to do things.

I THEN MADE SOME CHANGES

So, I updated my query to look like this (Query2):

SELECT students.student_id, period_one.score, period_one.subject_id, 
period_two.score, period_two.subject_id, period_three.score, 
period_three.subject_id
from students

LEFT JOIN period_one
ON students.student_id = period_one.student_id

LEFT JOIN period_two
ON students.student_id = period_two.student_id

LEFT JOIN period_three 
ON students.student_id = period_three.student_id

WHERE students.student_id = 3 OR period_one.student_id = 3 OR period_two.student_id = 3 OR period_three.student_id = 3

This works perfectly and since the students table is the main table which all the period tables are referencing. With this if a student id is not within the period_one and period_two table but period_there, the studentId, subjectId, and score is return for that table.

THEN ANOTHER PROBLEM POPS OUT

Before I updated my code I was displaying records a bit the way I wanted it, but wasn't getting/retrieving records the desire way. That was what prompted me to change my query, because I noticed it was the issue.

Now, based on my first query(Query1) I was selecting the subject_id from the various tables in the select statement. When I'm displaying records I passed that subject_id return from the query into a function that gets the subject name for that id. This is how I was displaying my results:

enter image description here

This works if the student id is within the table assign to the from clause, otherwise it returns nothing. That was why I change my code.

But now that I have change my code to (Query2) I'm unable to display the subject id and its name because it is not within the students table. Here is a gist on how I'm displaying my records: https://gist.github.com/nathansiafa/e9d22791800d4ba3a00e2b98de52baec

Is there a way which I can make it work better? Will appreciate suggestions as well as feed backs. Thanks!

  • 写回答

2条回答 默认 最新

  • dq804806 2017-04-24 14:29
    关注

    It seems that you are overthinking it a bit from a technical/programatical perspective and not focusing on the semantical meaning of the data you want to have.

    What you really want is a list of subjects, and the scores for those subjects for a particular student. The student is somewhat orthogonal here, because are are building a table, but Student is not part of that table.

    So step 1 would be to select the data we want - subjects and the scores for them:

    SELECT s.subject_id, s.subject_name, p1.score period_1_score, p2.score period_2_score, p3.score period_3_score 
    FROM subject s
    LEFT JOIN period_one p1 ON p1.subject_id = s.subject_id 
        AND p1.student_id = 10
    LEFT JOIN period_two p2 ON p2.subject_id = s.subject_id 
        AND p2.student_id = 10
    LEFT JOIN period_three p3 ON p3.subject_id = s.subject_id 
        AND p3.student_id = 10
    ORDER BY s.subject_name;
    

    This will give you the table data you want - first of all the subjects, and then the scores where they exist.

    Now, if you insist to load student data within the same query (I would advise to have a separate query SELECT * FROM student WHERE student_id=10 for just that), then you can left-join it on top:

    SELECT s.subject_id, s.subject_name, p1.score period_1_score, p2.score period_2_score, p3.score period_3_score, st.name student_name
    FROM subject s
    LEFT JOIN period_one p1 ON p1.subject_id = s.subject_id 
        AND p1.student_id = 10
    LEFT JOIN period_two p2 ON p2.subject_id = s.subject_id 
        AND p2.student_id = 10
    LEFT JOIN period_three p3 ON p3.subject_id = s.subject_id 
        AND p3.student_id = 10
    LEFT JOIN student st ON st.student_id = 10
    ORDER BY s.subject_name;
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥15 复杂网络,变滞后传递熵,FDA
  • ¥20 csv格式数据集预处理及模型选择
  • ¥15 部分网页页面无法显示!
  • ¥15 怎样解决power bi 中设置管理聚合,详细信息表和详细信息列显示灰色,而不能选择相应的内容呢?
  • ¥15 QTOF MSE数据分析
  • ¥15 平板录音机录音问题解决