问题:
如何显示学生未参加的每门课程的学生姓名,部门名称和课程名称?
我尝试使用这样生成笛卡尔积:
SELECT
NAME, student.dept_name, title
FROM
student
JOIN
(SELECT
id, title
FROM
takes, course
WHERE
takes.course_id <> course.course_id) a ON student.id = a.id
ORDER BY
NAME ASC, title ASC
只要学生只参加1门课程,它就能正常工作,但如果他参加不止一门课程,那就不行了
你们能提供解决方案吗?提前致谢
所需的输出是此格式值的连接
| name | dept_name | title (course name) |
答案 0 :(得分:1)
事实上,学生之间没有联系,学生不是一个问题,你需要知道学生可以采取的所有课程
学生
Name CourseId
---------- ----------
Zishan 1,2,3
Ellen 2,3,4
(2 row(s) affected)
场
courseid coursename
----------- ----------
1 java
2 C++
3 oracle
4 dot net
Courses_taken
sid cid
-------------------- -----------
zishan 1
zishan 2
(2 row(s) affected)
像这样的交叉连接
select s.Name Studentname, c.courseid cid,c.coursename CourseNAme
from student s
cross join course c
结果
Studentname cid CourseNAme
----------- ----------- ----------
Zishan 1 java
Zishan 2 C++
Zishan 3 oracle
Zishan 4 dot net
Ellen 1 java
Ellen 2 C++
Ellen 3 oracle
Ellen 4 dot net
加入courses_taken
select sc.Studentname,sc.Coursename,ct.cid
from
(
select s.Name Studentname, c.courseid cid,c.coursename CourseNAme
from student s
cross join course c
) sc
left join courses_taken ct on sc.StudentName = ct.sid and sc.cid = ct.cid
导致此
Studentname Coursename cid
----------- ---------- -----------
Zishan java 1
Zishan C++ 2
Zishan oracle NULL
Zishan dot net NULL
Ellen java NULL
Ellen C++ NULL
Ellen oracle NULL
Ellen dot net NULL
要排除在条件
时采用null的课程select sc.Studentname,sc.Coursename,ct.cid
from
(
select s.Name Studentname, c.courseid cid,c.coursename CourseNAme
from student s
cross join course c
) sc
left join courses_taken ct on sc.StudentName = ct.sid and sc.cid = ct.cid
where ct.cid is null
结果
Studentname Coursename cid
----------- ---------- -----------
Zishan oracle NULL
Zishan dot net NULL
Ellen java NULL
Ellen C++ NULL
Ellen oracle NULL
Ellen dot net NULL
(6 row(s) affected)
答案 1 :(得分:0)
通过进行笛卡尔联接来获取获得学生和课程的所有组合的查询,然后通过执行第二个查询除去,删除学生已完成的所有课程。这会处理尚未完成任何课程的学生,这就是为什么不存在不起作用的原因。
Select s.id, c.title
From student s cross join courses c
Except
Select t.id, c.title
From takes t join courses c on t.course_id = c.course_id
答案 2 :(得分:0)
select
s.*, c.*
from students s
cross join courses c
left join takes t on s.student_id = t.id -- naming looks weird
and c.course_id = t.course_id
where t.student_id IS NULL
order by
s.name, c.title -- or similar
cross join
形成Cartesian product
,形成学生+课程的所有组合。外部联接,将大量潜力设置为注册课程的实际学生组。然后,未加入的行构成了(每个)学生没有学过的课程。
如果问题有一个小小的“扭曲”,那么您需要的就是未参加课程的列表:
select distinct
c.*
from students s
cross join courses c
left join takes t on s.student_id = t.id -- naming looks weird
and c.course_id = t.course_id
where t.student_id IS NULL
order by
c.title -- or similar
将结果简化为未完成的课程。