我只是一个SQL的初学者,我有我无法解决的问题。
问题如下:
我有四张桌子
Student: matrnr, name, semester, start_date
Listening: matrnr<Student>, vorlnr<Subject>
Subject: vorlnr, title, sws, teacher<Professor>
Professor: persnr, name, rank, room我需要列出所有的学生,谁是听某教授的主题以萨莫的名字。
编辑:
select s.*
from Student s, Listening h
where s.matrnr=h.matrnr
and h.vorlnr in (select v.vorlnr from Subject v, Professor p
where v.gelesenvon=p.persnr and p.name='Kant');这就是我解决它的方法,但我不确定它是否是最佳解决方案。
发布于 2014-11-08 16:13:41
你的方法很好。只是,你想向学生展示,但加入学生的名单,从而得到学生名单组合。
此外,您还使用过时的联接语法。它在二十多年前被显式连接(内连接、交叉连接等)所取代。
您只能使用子查询来完成此任务:
select *
from Students,
where matrnr in
(
select matrnr
from Listening
where vorlnr in
(
select vorlnr
from Subject
where gelesenvon in
(
select persnr
from Professor
where name='Kant'
)
)
);或加入其他表格:
select *
from Students
where matrnr in
(
select l.matrnr
from Listening l
inner join Subject s on s.vorlnr = l.vorlnr
inner join Professor p on p.persnr = s.gelesenvon and p.name='Kant'
);或存在:
select *
from Students s
where exists
(
select *
from Listening l
inner join Subject su on su.vorlnr = l.vorlnr
inner join Professor p on p.persnr = su.gelesenvon and p.name='Kant'
where l.matrnr = s.matrnr
);有些人喜欢加入任何东西,然后使用不同的方式进行清理。这很容易编写,特别是因为您不必首先考虑查询。但出于同样的原因,当涉及更多的表和更多的逻辑(比如聚合)时,它会变得非常复杂,而且它也会变得很难阅读。
select distinct s.*
from Students s
inner join Listening l on l.matrnr = s.matrnr
inner join Subject su on su.vorlnr = l.vorlnr
inner join Professor p on p.persnr = su.gelesenvon and p.name='Kant';最后,这是一个品味的问题。
发布于 2014-11-08 16:23:52
当您遇到SQL问题时,表示问题的一个好方法是将表显示为CREATE TABLE语句。这些语句显示详细信息,例如列的类型以及哪些列是主键。此外,这允许我们实际构建一个小型数据库,以便重现错误的行为或仅仅测试我们的解决方案。
CREATE TABLE Student
(
matrnr NUMBER(9) PRIMARY KEY,
name NVARCHAR2(50),
semester NUMBER(2),
start_date DATE
);
CREATE TABLE Listening
(
matrnr NUMBER(9), -- Student
vorlnr NUMBER(9), -- Subject
CONSTRAINT PK_Listening PRIMARY KEY (matrnr, vorlnr)
);
CREATE TABLE Subject
(
vorlnr NUMBER(9) PRIMARY KEY,
title NVARCHAR2(50),
sws NVARCHAR2(50),
teacher NUMBER(9) -- Professor
);
CREATE TABLE Professor
(
persnr NUMBER(9) PRIMARY KEY,
name NVARCHAR2(50),
rank NUMBER(3),
room NVARCHAR2(50)
);使用此模式,我的解决方案如下所示:
SELECT *
FROM
Student
WHERE
matrnr IN (
SELECT L.matrnr
FROM
Listening L
INNER JOIN Subject S
ON L.vorlnr = S.vorlnr
INNER JOIN Professor P
ON S.teacher = P.persnr
WHERE P.name = 'Kant'
);你可以在这里找到它:http://sqlfiddle.com/#!4/5179dc/2
因为我没有插入任何记录,所以它唯一要测试的是表和列名的语法和正确使用。
你的解决方案不太理想。它不区分连接表和指定为WHER-子句的附加条件。如果每个学生参加教授的几门课程,就能产生几个成绩记录。因此,我的解决方案将所有其他表放入子选择中。
发布于 2014-11-08 15:45:06
select st.name
from student st
join listening l on l.matrnr = st.matrnr
join subject su on su.vorlnr = l.vorlnr
join professor p on su.teacher = p.persnr
where p.name = 'some name'https://stackoverflow.com/questions/26818864
复制相似问题