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条)

报告相同问题?

悬赏问题

  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP