MySQL从一个表中选择所有记录,从另一个表中选择它们的匹配/ NULL

时间:2016-04-07 20:40:31

标签: mysql

我有三张桌子。其中两个是单独的无关表(学生和科目),第三个(条目)是用外键(student_id和subject_id)链接它们的一个。

以下是包含记录的所有表格:

生:

+------------+------------+-----------+---------------------+---------------------+
| student_id | first_name | surname   | email               | reg_date            |  
+------------+------------+-----------+---------------------+---------------------+
|          1 | Emily      | Jackson   | emilym@gmail.com    | 2012-10-14 11:14:13 |
|          2 | Daniel     | ALexander | daniela@hotmail.com | 2014-08-19 08:08:23 |
|          3 | Sarah      | Bell      | sbell@gmail.com     | 1998-07-04 13:16:32 |
|          4 | Alex       | Harte     | AHarte@hotmail.com  | 1982-06-14 00:00:00 |
+------------+------------+-----------+---------------------+---------------------+    

主题:

+------------+--------------+------------+----------------+
| subject_id | subject_name | exam_board | level_of_entry |
+------------+--------------+------------+----------------+
|          1 | Art          | CCEA       | AS             |
|          2 | Biology      | CCEA       | A              |
|          3 | Computing    | OCR        | GCSE           |
|          4 | French       | CCEA       | GCSE           |
|          5 | Maths        | OCR        | AS             |
|          6 | Chemistry    | CCEA       | GCSE           |
|          7 | Physics      | OCR        | AS             |
|          8 | RS           | CCEA       | GCSE           |
+------------+--------------+------------+----------------+    

输入:

+----------+---------------+---------------+------------+
| entry_id | student_id_fk | subject_id_fk | entry_date |
+----------+---------------+---------------+------------+
|        1 |             1 |             1 | 2012-10-15 |
|        2 |             1 |             4 | 2011-09-21 |
|        3 |             1 |             3 | 2015-08-10 |
|        4 |             2 |             6 | 1992-07-13 |
|        5 |             3 |             7 | 2013-02-12 |
|        6 |             3 |             8 | 2016-01-14 |
+----------+---------------+---------------+------------+

我如何选择所有学生的名字(students.first_name),以及他们所拥有的主题条目的名称(subjects.subject_name)?我的意思是所有的学生姓名都被退回,并且他们的条目的所有主题名称都列在他们旁边,对于没有任何条目的人来说是NULL。我也希望它按字母顺序按first_name分组。

我希望输出类似于:

first_name    subject_name
--------------------------
Alex          NULL
Daniel        Chemistry
Emily         French
Emily         Computing
Sarah         Physics
Sarah         RS

虽然我不确定这是否完全正确。

我的猜测是这样的:

SELECT students.first_name, subjects.subject_name
FROM students
JOIN entries ON entries.student_id_fk = students.student_id
JOIN subjects ON entries.subject_id_fk = subjects.subject_id
GROUP BY  students.first_name;

我唯一不确定的是使用哪个联接以及放置它的位置,或者表格是否需要以不同的顺序列出。我认为它应该是左联盟,但我不确定。

非常感谢帮助!

4 个答案:

答案 0 :(得分:1)

我认为这可能是查询但是使用order by而不是group by(group by用于聚合函数,如count()或max())

SELECT students.first_name, subjects.subject_name
FROM entries
LEFT JOIN students ON entries.student_id_fk = students.student_id
LEFT JOIN subjects ON entries.subject_id_fk = subjects.subject_id
ORDER  BY  students.first_name;

答案 1 :(得分:1)

您应该使用左连接,因为您还要为没有分配主题的学生返回行。另外,您想要对结果进行排序,而不是组。所以最终应该是这样的:

SELECT students.first_name, subjects.subject_name
FROM students
LEFT JOIN entries ON entries.student_id_fk = students.student_id
LEFT JOIN subjects ON entries.subject_id_fk = subjects.subject_id
ORDER BY  students.first_name;

答案 2 :(得分:0)

您可能需要LEFT OUTER JOIN

select stu.first_name, sub.subject_name
from students stu
join entries e
on stu.student_id = e.student_id_fk
left outer join subjects sub
on sub.subject_id = e.subject_id_fk
order by stu.first_name;

我安装了任何SQL都离开了我的电脑,所以这是未经测试的,但应该给你你想要的东西。

  • 修改了我的答案,将group by替换为其他人指出的order by。这是正确的方法,除非该组作为更大的查询的一部分,你可能已经删除。

答案 3 :(得分:0)

左连接学生表依次是剩下的两个表,是抓住所有学生名字的正确选择。

要订购名称排序。

我已经创建了一个sql小提琴,可以更好地显示如何获得所需的输出。

以下是链接:http://sqlfiddle.com/#!9/a1c850/7

查询

select students.student_name, subjects.subject_name
from 
students
left join entries on entries.student_id=students.student_id
left join subjects on entries.subject_id=subjects.subject_id
order by students.student_name;