【问题标题】:postgresql multiple subqueriespostgresql 多个子查询
【发布时间】:2013-12-08 11:03:44
【问题描述】:

我手头有一项任务,要求我返回一名学生的详细信息,该学生参加了一位姓 Hoffman 的老师教授的课程,但我被困住了。

    SELECT * FROM Public."Class" WHERE tid=(
        SELECT tid FROM Public."Tutor" WHERE tname LIKE '%Hoffman');

这让我回到了霍夫曼教授的课程,但从这里我不知道该去哪里。我相信我必须访问“已注册”表,然后最后是学生表,但尝试无济于事。以下查询是我在中断查询之前得到的 -_- 我确定我必须使用 HAVINGIN 关键字,但我不太知道如何处理它们!

SELECT * FROM Public."Student" WHERE programme='IT' (
    SELECT * FROM Public."Class" WHERE tid=(
        SELECT tid FROM Public."Tutor" WHERE tname LIKE '%Hoffman')
    );

任何帮助将不胜感激!

数据库结构如下:-

Student(sid integer, sname varchar(20), programme varchar(4), level integer, age integer) 
Class(ccode varchar(6), cname varchar(25), week_day varchar(3), meets_at time, room 
varchar(6), tid integer) 
Enrolled(sid integer, ccode varchar(6)) 
Tutor(tid integer, tname varchar(20))

再次感谢:)

更新:-

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';

【问题讨论】:

标签: postgresql subquery pgadmin


【解决方案1】:

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

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';

【讨论】:

  • 非常感谢,我只能接受一个答案并选择了@Miguelo 的答案,因为他包含了程序限制,但这似乎同样可以接受!
  • @蒂米。没问题。我不确定这是否是一项要求,因为你没有在描述中提到它,所以我没有包括它。
【解决方案2】:

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

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'
  );

【讨论】:

  • 我正在使用 DISTINCT。这是不正确的吗?我将更新帖子以显示当前查询
  • 重点是:你不需要需要与众不同。学生表中的学生已经是唯一的。 (我相信)。如果您不生成重复项,则不必排除它们。
【解决方案3】:

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

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' 

【讨论】:

  • @Timmy 另外,一个正确的基于子查询的查询可能会被优化器转换为上述基于连接的查询。它更喜欢在可能的情况下展平子查询。通常,只有在无法使用连接完成所需操作时,才需要子查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
  • 2015-05-06
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
相关资源
最近更新 更多