我有一个包含3个表的数据库:students
,courses
和mistakes
。我有一个联接表(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_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表中有记录的学生,但不会显示所请求课程的学生。
如何让这些学生进入成绩表?
答案 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 | |