【问题标题】:Postgresql: One-To-Many Relationship With Multiple Conditions On The Many SidePostgresql:在多方面具有多个条件的一对多关系
【发布时间】:2020-12-07 07:44:37
【问题描述】:

我有一个包含以下列的学生表

id
student_name

课程表

id
student_id  //a foreign key
course_name
credits

这是一对多的关系(一个学生可能有多个课程)。

我想列出所有有这 2 门课程的学生

first course:   course_name -> math    , credit -> 5
second course:  course_name -> history , credit -> 3

请注意,每个学生都必须至少有这两门课程。

我可以通过两次加入课程表来获得我想要的东西(一次用于第一门课程,另一次用于第二门课程),但如果我想再添加一门课程,我将需要再加入一门时间。

那么请您指导我另一种方法。

【问题讨论】:

  • 您希望每个学生完全上这两个课程,还是至少上这两个课程(但可以有更多)
  • 与您的问题无关,但这不应该是多对多的关系吗?一门课程可以包含多名学生,一名学生注册多门课程
  • 至少这2门课程
  • 不错,多对多比较好,不过我只是用这个例子把问题简单化了

标签: sql postgresql join relational-division in-subquery


【解决方案1】:

这能解决您的问题吗?我计算了您预期课程的所有出现次数,总和必须是 2

demo:db<>fiddle

SELECT
    s.id
FROM students s
JOIN courses c
ON c.student_id = s.id
GROUP BY s.id
HAVING SUM(
    ((c.course_name = 'math' AND c.credits = 5)
    OR
    (c.course_name = 'history' AND c.credits = 3))::int
) = 2

除了SUM(condition::int),您还可以将COUNT()FILTER 子句一起使用:

demo:db<>fiddle

HAVING COUNT(*) FILTER (WHERE
    (c.course_name = 'math' AND c.credits = 5)
    OR
    (c.course_name = 'history' AND c.credits = 3)
) = 2

【讨论】:

  • 感谢您为答案付出的努力,它在演示中看起来不错,但为了使其适用于我的情况,我试图了解当您使用 OR 时总和是 2,所以我试过这个select (true or true)::int as x ,它给了我1,正如我所料。你能解释一下你是如何得到总和 2 的吗?
  • 你是对的:bool 条件给出 0 或 1。因为 student _id == 2(在我的小提琴中)两次匹配这个条件(第一次是 math,第二次是 history 记录) ,两个匹配的和是2。所以,如果你需要添加第三个条件,总和必须是3,因为表必须满足条件3次。我在这里添加了中间步骤:dbfiddle.uk/…
  • 感谢您的解释和优雅的解决方案
猜你喜欢
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多