首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >连接4个表

连接4个表
EN

Stack Overflow用户
提问于 2014-11-08 15:42:23
回答 4查看 64关注 0票数 2

我只是一个SQL的初学者,我有我无法解决的问题。

问题如下:

我有四张桌子

代码语言:javascript
复制
Student: matrnr, name, semester, start_date
Listening: matrnr<Student>, vorlnr<Subject>
Subject: vorlnr, title, sws, teacher<Professor>
Professor: persnr, name, rank, room

我需要列出所有的学生,谁是听某教授的主题以萨莫的名字。

编辑:

代码语言:javascript
复制
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');

这就是我解决它的方法,但我不确定它是否是最佳解决方案。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-11-08 16:13:41

你的方法很好。只是,你想向学生展示,但加入学生的名单,从而得到学生名单组合。

此外,您还使用过时的联接语法。它在二十多年前被显式连接(内连接、交叉连接等)所取代。

您只能使用子查询来完成此任务:

代码语言:javascript
复制
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'
    )
  )
);

或加入其他表格:

代码语言:javascript
复制
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'
);

或存在:

代码语言:javascript
复制
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
);

有些人喜欢加入任何东西,然后使用不同的方式进行清理。这很容易编写,特别是因为您不必首先考虑查询。但出于同样的原因,当涉及更多的表和更多的逻辑(比如聚合)时,它会变得非常复杂,而且它也会变得很难阅读。

代码语言:javascript
复制
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';

最后,这是一个品味的问题。

票数 3
EN

Stack Overflow用户

发布于 2014-11-08 16:23:52

当您遇到SQL问题时,表示问题的一个好方法是将表显示为CREATE TABLE语句。这些语句显示详细信息,例如列的类型以及哪些列是主键。此外,这允许我们实际构建一个小型数据库,以便重现错误的行为或仅仅测试我们的解决方案。

代码语言:javascript
复制
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)
);

使用此模式,我的解决方案如下所示:

代码语言:javascript
复制
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-子句的附加条件。如果每个学生参加教授的几门课程,就能产生几个成绩记录。因此,我的解决方案将所有其他表放入子选择中。

票数 3
EN

Stack Overflow用户

发布于 2014-11-08 15:45:06

代码语言:javascript
复制
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'
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26818864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档