SQL Server以特定格式显示查询输出

时间:2017-11-17 07:13:23

标签: sql sql-server database

问题:

如何显示学生未参加的每门课程的学生姓名,部门名称和课程名称?

我尝试使用这样生成笛卡尔积:

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门课程,它就能正常工作,但如果他参加不止一门课程,那就不行了

你们能提供解决方案吗?提前致谢

Database relations

所需的输出是此格式值的连接

| name | dept_name | title (course name) |

3 个答案:

答案 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

将结果简化为未完成的课程。