加入后如何获取一个表的所有行?

时间:2019-02-25 21:03:17

标签: mysql sql

我有一个包含3个表的数据库:studentscoursesmistakes。我有一个联接表(csm),在其中连接了3个表。我想每个课程的错误都是一样的。

餐桌课程

+----------+---------------+
| crs_id   | crs_name      |
+----------+---------------+
| 1        | HTML          |
| 2        | PHP           |
| 3        | Python        |
+----------+---------------+

餐桌学生

+----------+---------------+---------------+
| stu_id   | stu_firstname | stu_lastname  |
+----------+---------------+---------------+
| 1        | Tina          | Turner        |
| 2        | Lisa          | Laroi         |
| 3        | Dina          | Donna         |
| 3        | Jim           | Leduc         |
+----------+---------------+---------------+

表格错误

+----------+---------------+------------+
| mis_id   | mis_name      | mis_weight |
+----------+---------------+------------+
| 1        | No camelCase  | 7          |
| 2        | No brackets   | 10         |
| 3        | Operator mist.| 12         |
+----------+---------------+------------+

联接表CSM

+----------+------------+------------+------------+
| csm_id   | fk_crs_id  | fk_stu_id  | fk_mis_id  |
+----------+------------+------------+------------+
| 1        | 1          | 1          | 1          |
| 2        | 1          | 1          | 3          |
| 3        | 2          | 3          | 1          |
| 4        | 3          | 2          | 2          |
| 5        | 3          | 2          | 1          |
| 6        | 3          | 3          | 1          |
+----------+------------+------------+------------+

如果我选择一门特定的课程,我想获得该课程的所有学生及其减分的列表。因此,我也想让加入表csm中没有结果的学生。

我得到的最接近的结果是以下sql语句:

select stu_firsname, stu_lastname, csm.*, sum(mis_weight) 
from students s
left join crs_stu_mis csm on s.stu_id = csm.fk_stu_id
left join mistakes m on csm.fk_mis_id = m.mis_id
where fk_crs_id = 4 or fk_crs_id is null
group by stu_firstname;

通过此操作,我可以得出某门课程的错误总和,以及在CSM表中没有任何记录但缺少某些结果的学生。例如,它不会显示在CSM表中有记录的学生,但不会显示所请求课程的学生。

如何让这些学生进入成绩表?

2 个答案:

答案 0 :(得分:0)

如果您的主要数据在CSM表中,请尝试以下操作:

select s.stu_firsname, s.stu_lastname, csm.*, sum(m.mis_weight) from crs_stu_mis csm
join  students s on s.stu_id = csm.fk_stu_id
join mistakes m on csm.fk_mis_id = m.fou_id
csm.fk_crs_id = 4
group by s.stu_naam;

第二种情况: 您的数据可能会受到分组属性的影响,请尝试将其设置为非NULL,例如:

select s.stu_firsname, s.stu_lastname, csm.*, sum(m.mis_weight) from crs_stu_mis csm
join  students s on s.stu_id = csm.fk_stu_id
join mistakes m on csm.fk_mis_id = m.fou_id
csm.fk_crs_id = 4
group by csm.csm_id;

答案 1 :(得分:0)

在您的查询中:

left join crs_stu_mis csm on s.stu_id = csm.fk_stu_id`
...
where fk_crs_id = 4 or fk_crs_id is null

这并不是您想要的,因为这种情况将过滤掉csm表中有记录的学生,仅记录4以外的课程。您想将该条件移至相应的LEFT JOIN

left join crs_stu_mis csm on s.stu_id = csm.fk_stu_id AND csm.fk_crs_id = 4

另一个潜在的问题来源是查询处理聚合的方式。 SELECT子句中有未聚合的列,这些列未出现在GROUP BY子句中。此语法不是良好的SQL编码实践,并且自MySQL 5.7版以来不再受支持。我假设您要为每个学生的成绩记录一个。

查询:

select 
    s.stu_firstname, 
    s.stu_lastname, 
    sum(m.mis_weight) total_misses_weight
from 
    students s
    left join crs_stu_mis csm on s.stu_id = csm.fk_stu_id AND csm.fk_crs_id = 3
    left join mistakes m on csm.fk_mis_id = m.mis_id
group by 
    s.stu_id, 
    s.stu_firstname, 
    s.stu_lastname

Demo on DB Fiddle 的课程ID 3

| stu_firstname | stu_lastname | total_misses_weight |
| ------------- | ------------ | ------------------- |
| Tina          | Turner       |                     |
| Lisa          | Laroi        | 17                  |
| Dina          | Donna        | 7                   |
| Jim           | Leduc        |                     |