postgresql多个子查询

postgresql多个子查询,postgresql,subquery,pgadmin,Postgresql,Subquery,Pgadmin,我手头有一项任务,要求我返回一名学生的详细信息,该学生是由一位姓霍夫曼的老师授课的,我被卡住了 SELECT * FROM Public."Class" WHERE tid=( SELECT tid FROM Public."Tutor" WHERE tname LIKE '%Hoffman'); 这让我想起了霍夫曼教授的课程,但我不知道该去哪里。我相信我必须访问“已注册”表,然后是“学生”表,但尝试了无效。下面的查询是我在中断查询之前得到的-我肯定我将不得不使用HAV

我手头有一项任务,要求我返回一名学生的详细信息,该学生是由一位姓霍夫曼的老师授课的,我被卡住了

    SELECT * FROM Public."Class" WHERE tid=(
        SELECT tid FROM Public."Tutor" WHERE tname LIKE '%Hoffman');
这让我想起了霍夫曼教授的课程,但我不知道该去哪里。我相信我必须访问“已注册”表,然后是“学生”表,但尝试了无效。下面的查询是我在中断查询之前得到的-我肯定我将不得不使用
HAVING
IN
关键字,但我不知道如何处理它们

SELECT * FROM Public."Student" WHERE programme='IT' (
    SELECT * FROM Public."Class" WHERE tid=(
        SELECT tid FROM Public."Tutor" WHERE tname LIKE '%Hoffman')
    );
任何帮助都将不胜感激

数据库结构如下:-

再次感谢:)

更新:-

SELECT DISTINCT *
FROM Public."Student" s
INNER JOIN Public."Enrolled" e ON e.sid = s.sid
INNER JOIN Public."Class" c ON c.ccode = e.ccode
INNER JOIN Public."Tutor" t ON t.tid = c.tid
WHERE programme='IT' AND t.tname LIKE '%Hoffman';

您不需要为每个验证执行子查询。这可以通过连接轻松完成:

SELECT s.*
FROM Student s
INNER JOIN Enrolled e ON e.sid = s.sid
INNER JOIN Class c ON c.ccode = e.ccode
INNER JOIN Tutor t ON t.tid = c.tid
WHERE t.tname LIKE '%Hoffman';

您不需要为每个验证执行子查询。这可以通过连接轻松完成:

SELECT s.*
FROM Student s
INNER JOIN Enrolled e ON e.sid = s.sid
INNER JOIN Class c ON c.ccode = e.ccode
INNER JOIN Tutor t ON t.tid = c.tid
WHERE t.tname LIKE '%Hoffman';

您可以使用联接而不是子查询来解决此问题

SELECT * FROM Public."Student"  s
join Public.Enrolled e on (s.sid= e.id)
join Public.Class c on (c.ccode = e.ccode)
join Public.Tutor t on (c.tid = t.tid)
WHERE s.programme='IT' and  t.tname like  '%Hoffman' 

您可以使用联接而不是子查询来解决此问题

SELECT * FROM Public."Student"  s
join Public.Enrolled e on (s.sid= e.id)
join Public.Class c on (c.ccode = e.ccode)
join Public.Tutor t on (c.tid = t.tid)
WHERE s.programme='IT' and  t.tname like  '%Hoffman' 

上述两种解决方案将导致学生在同一位老师的多个班级注册时被多次报告。如果查询的唯一目标是只选择一次学生,那么下面的查询将完全做到这一点

SELECT *
FROM Student s
WHERE s.programme = 'IT'
AND EXISTS (
  SELECT * 
  FROM Enrolled e
  JOIN Class c ON c.ccode = e.ccode
  JOIN Tutor t ON t.tid = c.tid
  WHERE e.sid = s.sid
  AND t.tname LIKE '%Hoffman'
  );

上述两种解决方案将导致学生在同一位老师的多个班级注册时被多次报告。如果查询的唯一目标是只选择一次学生,那么下面的查询将完全做到这一点

SELECT *
FROM Student s
WHERE s.programme = 'IT'
AND EXISTS (
  SELECT * 
  FROM Enrolled e
  JOIN Class c ON c.ccode = e.ccode
  JOIN Tutor t ON t.tid = c.tid
  WHERE e.sid = s.sid
  AND t.tname LIKE '%Hoffman'
  );

非常感谢,我只能接受一个答案,并同意@Miguelo的答案,因为他包括了节目限制,但这似乎同样可以接受@提米。没问题。我不确定这是否是一项要求,因为你在描述中没有提到,所以我没有包括在内。非常感谢,我只能接受一个答案,并同意@Miguelo的答案,因为他包括了计划限制,但这似乎同样可以接受@提米。没问题。我不确定这是否是一个要求,因为您在描述中没有提到,所以我没有包括它。我使用的是DISTINCT。这是不对的吗?我会更新帖子来显示当前的问题,重点是:你们不需要区分。学生表中的学生已经是唯一的。(我想是吧)。如果不生成重复项,则不必排除它们。我使用的是DISTINCT。这是不对的吗?我会更新帖子来显示当前的问题,重点是:你们不需要区分。学生表中的学生已经是唯一的。(我想是吧)。如果不生成重复项,则不必排除它们。@Timmy同样,正确的基于子查询的查询可能会被优化器转换为上述基于联接的查询。如果可能的话,它更喜欢将子查询展平。一般来说,只有在无法对联接执行所需操作时才需要子查询。@Timmy另外,正确的基于子查询的查询可能会被优化器转换为上述基于联接的查询。如果可能的话,它更喜欢将子查询展平。一般来说,只有在无法使用联接执行所需操作时才需要子查询。Pg教程非常值得一看:。(并非尖刻,只是为开始使用SQL的人提供了一个诚实的建议)。Pg教程非常值得一看:。(不是说脏话,只是为开始使用SQL的人提供一个诚实的建议)。