选择完全满足给定先决条件列表的课程

Posted

技术标签:

【中文标题】选择完全满足给定先决条件列表的课程【英文标题】:Select courses that are completely satisfied by a given list of prerequisites 【发布时间】:2013-12-19 00:58:05 【问题描述】:

我正在尝试编写一个 SQL 查询,该查询将返回一个人有资格参加的课程列表,给出他们已完成科目的列表(用作先决条件)。

我的数据库是这样布局的。

   Prerequisite:
   +---------------+---------------+
   |      Id       |     Name      |         (Junction table)
   |---------------|---------------|         CoursePrerequisites:
   |      1        |   Maths       |         +---------------+---------------+
   |      2        |   English     |         |  Course_FK    | Prerequisite_FK
   |      3        |   Art         |         |---------------|---------------|
   |      4        |   Physics     |         |      1        |      1        |
   |      5        |   Psychology  |         |      1        |      2        |
   +-------------------------------+         |      2        |      3        |
                                             |      2        |      5        |
   Course:                                   |      5        |      4        |
   +---------------+---------------+         +---------------v---------------+
   |      Id       |     Name      |
   |---------------|---------------|
   |      1        |   Course1     |
   |      2        |   Course2     |
   |      3        |   Course3     |
   |      4        |   Course4     |
   |      5        |   Course5     |
   +---------------v---------------+

我一直在试验如下查询:

    SELECT  DISTINCT C.*
        FROM    Course C
    INNER JOIN JNCT_Course_Prerequisites cp
        ON C.Id = cp.Course_FK
    WHERE   cp.Prerequisite_FK IN (SELECT Prerequisites.Id FROM Prerequisites Where Name = 'Art' AND Name = etc etc)

但是,这会返回以艺术为先决条件的任何课程,而不仅仅是由给定的先决条件列表完全满足的课程。例如。它将返回课程 2,仅将艺术作为学生的先决条件,即使该课程还需要心理学。

我对 SQL 很陌生,所以如果我的表格布局等有问题,或者这是一个看似简单的问题,请原谅。我一直在尽我所能四处寻找,但只能找到似乎是解决这个问题的反面的方法。

看来我需要做一些不同的设置:

构建一组具有先决条件的课程(针对每个先决条件?) 构建一组没有先决条件的课程 执行不同的集合操作:选择所有存在于第一个集合中且不存在于第二个集合中 看起来很简单,但我现在对联结表以及如何在许多先决条件下处理它感到困惑。

我希望返回至少完全满足给定先决条件列表的行,而不是包含至少一个先决条件的行。

例如,如果给出了先决条件“Art”、“English”、“Psychology”,则应该返回的唯一行是 Course2 的行(先决条件不满足)。

谢谢

【问题讨论】:

您使用的是哪种 RDBMS(SQL 风格)? 您在 CoursePrerequisites 上的第二行是重复的。这是对的还是错字?顺便说一句,格式很好:) 请根据您的示例数据显示所需的输出。 我将 mysql 用于 RDBMS。我将使所需的输出更清晰。 Jorge,CoursePrerequisite 表中的重复行不是错字。该表作为连接表服务器,以促进课程与其先决条件之间的多对多关系。如果一个课程 ID 被列出 2 次,则意味着它有 2 个先决条件。我相信我也为这种关系正确设置了表格(外键引用等)。 豪尔赫,对不起,你是对的。有一条重复的行(现已修复)。我立即得出结论,您正在考虑 Course_FK 字段有重复项。 【参考方案1】:
SELECT  * FROM Course C LEFT JOIN Course_Prerequisites cp ON C.Id = cp.Course_FK 
         WHERE Prerequisite_FK IN (SELECT Prerequisites.Id FROM Prerequisites Where Name = 'Art' OR Name = etc etc)
 NOT EXISTS   
   (SELECT  * FROM Course C LEFT JOIN Course_Prerequisites cp ON C.Id = cp.Course_FK 
         WHERE Prerequisite_FK NOT IN (SELECT Prerequisites.Id FROM Prerequisites Where Name = 'Art' OR Name = etc etc))

【讨论】:

“NOT EXISTS”关键字前是否应该有一个“AND”?【参考方案2】:

我能够通过以下查询解决问题(并且在此过程中还了解了一些关于 GROUP_CONCAT 的知识)。 GROUP_CONCAT 并不是真正需要的,但可以使输出更清晰。这也取决于 在“GROUP BY Course.id”上 - 如果不需要,可以将其删除。此解决方案执行必要的集合差异,并仅选择至少满足先决条件的课程。

我还是很陌生,所以如果有什么可以做得更好的,请告诉我。

SELECT Course.id, course.Name, GROUP_CONCAT(DISTINCT Prerequisite.Name) AS 'Prerequisite Name(s)'
FROM Course
  LEFT JOIN CoursePrerequisites ON Course.id = CoursePrerequisites.Course_FK
  LEFT JOIN Prerequisite ON Prerequisite.id = CoursePrerequisites.Prerequisite_FK 
WHERE NOT EXISTS 
  (SELECT 1
    FROM CoursePrerequisites 
    WHERE Course.id = CoursePrerequisites.Course_FK
      AND CoursePrerequisites.Prerequisite_FK NOT IN (SELECT Prerequisite.id FROM Prerequisite Where Name = 'Art' OR Name = 'English' OR Name = 'Psychology''))
GROUP BY Course.id;

【讨论】:

【参考方案3】:

1, SELECT Course_FK ,COUNT(1) AS Num FROM CoursePrerequisites GROUP BY Course_FK

并将结果存储在临时表 temp_a 中。

2, SELECT Course_FK ,COUNT(1) AS Num FROM CoursePrerequisites a INNER JOIN 先决条件 b ON a.Prerequisite_FK=b.Id GROUP BY Course_FK

并将结果存储在临时表 temp_b 中。

3, SELECT a.Course_FK FROM temp_a a INNER JOIN temp_b b ON a.Course_FK=b.Course_FK AND a.Num=b.Num

这将是合格课程的 ID

【讨论】:

以上是关于选择完全满足给定先决条件列表的课程的主要内容,如果未能解决你的问题,请参考以下文章

第279题:完全平方数

满足特定条件的列表的所有组合

JsonPath:如果满足条件,则选择根级别字段

Excel满足两个条件,求和的公式

如何更有效地从n组中找到满足给定条件的最小组合?

C中的程序,它读取声音数据并检查给定数据是不是满足wav文件的先决条件