我有三个表:成绩、作业、用户。我希望能够找到用户已完成和未完成的作业。我知道我们在这里使用 OUTER 联接,但我似乎无法获得正确的 SQL 来重现我想要的内容。在我的表格中,1 名学生完成了 1 项作业(显示 1、3、1 名学生完成了 2 项作业,1 名学生完成了 3 项作业,下面张贴了完整的表格
assignment table:
assignmentID | assignmentType | totalScore |
-------------|-----------------|------------|
1 | Assignment | 100 |
2 | Assignment | 100 |
3 | Assignment | 100 |
4 | Test | 200 |
grade table:
gradeID | studentID | assignmentID | grade |
---------|-------------|----------------|---------|
1 | 3 | 1 | 100 |
2 | 3 | 2 | 100 |
3 | 3 | 3 | 100 |
4 | 2 | 1 | 100 |
5 | 2 | 2 | 100 |
6 | 1 | 1 | 100 |
student table:
studentID | studentName |
-----------|-------------|
1 | John |
2 | Jane |
3 | Joe |
所以在上面的场景中, 约翰完成了 1 项作业,完成了 3 项作业,简完成了 2 项作业,完成了 2 项作业未完成,乔完成了 3 项作业,完成了 1 项作业未完成。
希望输出为:
studentID | achievementID | grade |
----------|---------------|-------|
1 | 1 | 100 |
1 | 2 | NULL |
1 | 3 | NULL |
1 | 4 | NULL |
2 | 1 | 100 |
2 | 2 | 100 |
2 | 3 | NULL |
2 | 4 | NULL |
3 | 1 | 100 |
3 | 2 | 100 |
3 | 3 | 100 |
3 | 4 | NULL |
非常感谢任何帮助。
最佳答案
您的新要求:http://www.sqlfiddle.com/#!2/23408/23
select s.studentID,
a.assignmentID as achievementID,
g.grade
from student s
cross join assignment a
left join grade g
on g.studentId = s.studentId
and g.assignmentID = a.assignmentID
order by s.studentID, achievementID
输出:
STUDENTID ACHIEVEMENTID GRADE
1 1 100
1 2
1 3
1 4
2 1 100
2 2 100
2 3
2 4
3 1 100
3 2 100
3 3 100
3 4
sqlfiddle 不会在其输出中将 NULL 显示为 NULL。尽管如此,上面空等级的基础空值是 NULL
也可以使用表逗号表,而不是使用CROSS JOIN;但这通常是不受欢迎的。很容易用逗号表提交无意的笛卡尔积,想象一下使用逗号表方法在三个或更多表上会产生多少行。这就是为什么在SQL中引入JOIN(INNER,LEFT,CROSS,FULL,NATURAL)关键字,使代码意图更加清晰
http://www.sqlfiddle.com/#!2/23408/37
select s.studentID,
a.assignmentID as achievementID,
g.grade
from (student s, assignment a)
left join grade g
on g.studentId = s.studentId
and g.assignmentID = a.assignmentID
order by s.studentID, achievementID
我宁愿使用 CROSS JOIN 关键字也不愿使用表逗号表。 CROSS JOIN 形式化了笛卡尔积的概念。 JOIN 通常会形式化您希望在查询中实现的目标。对于逗号表,很难从查询中推断出您的表是否会以inner-join-y 操作或left-join-y 操作等结束。
关于mysql - 如何获取所有学生和作业的列表以及成绩?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10377196/