【问题标题】:SQL Trouble with second part of WHERE NOT EXIST queryWHERE NOT EXIST 查询的第二部分的 SQL 问题
【发布时间】:2020-04-02 02:44:14
【问题描述】:

我正在尝试创建一个网站,根据学生成绩单中已完成的课程以及学位课程的剩余内容,向学生推荐他们下学期应该学习的课程。

我的第一个想法是查询课程中所有不在学生成绩单中的 Courses_Codes。我已经用下面的查询做到了。

SELECT Course_Code, Course_Sequence, Prereq_ID
FROM Curriculum 
WHERE NOT EXISTS
(SELECT * FROM Transcript 
WHERE curriculum.course_code = transcript.course_code
AND transcript.CWID = "C38475920"); 

但是,我需要进一步缩小查询范围,以免我向学生推荐具有学生不满足的课程先决条件的课程。课程表中的 Prereq_ID 包含每门课程的先决条件。我完全不知道如何在上面的查询中添加其他代码并获得返回所有课程的结果。不在特定学生成绩单中的 Course_Code (CWID 是学生的 ID。学生上过的每门课有相应的 CWID) 并且还可以通过添加类似这样的内容来确保满足先决条件? transcript.Course_Code = curriculum.Prereq_ID

如果这没有意义,我知道这不是正确的 SQL,但是:

SELECT curriculum.Course_Code
FROM curriculum 
WHERE curriculum.Course_Code  IS NOT IN transcript 
AND transcript.Course_Code = curriculum.Prereq_ID
AND transcript.CWID = "C38475920”;

这是课程表和成绩单:

protected $table ="curriculum";
    protected $fillable = [
      'Program_ID', //Primary Key //int
      'Curriculum_ID', //varchar
      'Maj_Code',//varchar
      'Course_Code',//varchar
      'Course_Seq', //int
      'Prereq_ID',//varchar
      'Course_Desc',//varchar
    ];
    protected $table ="transcript";
    protected $fillable = [
      'Transcript_ID', //primary key 
      'CWID', //foreign key //varchar
      'Maj_Code', //varchar
      'Curriculum_ID', //varchar
      'Course_Comp',//varchar
      'Term_Completed',//varchar
      'Course_Grade',//varchar
      'Course_Code',//varchar
    ];

希望这会使我试图弄清楚的结果。任何帮助将不胜感激。

【问题讨论】:

  • 我认为如果您edit 您的问题并发布架构详细信息(即表名、列名、列数据类型、主键和外键)会有所帮助。虽然这些细节您可能很清楚,但这并不意味着阅读您的问题的人知道这些细节。
  • 你是对的,对此感到抱歉。

标签: mysql sql


【解决方案1】:

您可能需要以下查询。您的问题令人困惑,因为您说“CWID 是学生的 ID”,但随后您又说“学生上的每个课程都有一个相应的 CWID”。因此,CWID 似乎不是学生的唯一 ID,也许它是学生和所学课程配对的唯一 ID。无论如何,您在上面发布的内容中可能缺少student 表,但我认为您可以通过拥有学生的成绩单ID 来解决您的问题。据推测,一个学生只能有一个成绩单 ID。

我的回答基于以下假设:

  1. 一个学生只能有一个transcript_id
  2. prereq_id 代表course_id,它是curriculum 表每一行上课程的先决条件
  3. course_id 是独一无二的,没有两个不同的课程可以共享相同的值(例如,跨越不同的 program_id 值)

我对@9​​87654328@ 的重要性感到困惑,因为您说该列是主键,但course_id 不是,在curriculum 表上。那没有意义。大概一个“程序”将是诸如生物学、教育、会计等之类的东西,并且此类程序将有 2 门以上的课程。 program_id 怎么可能是有 course_code 列的表上的主键,因为程序中必须有 2 门以上的课程......?

select    c.course_code
          c.course_sequence
          c.prereq_id
from      curriculum      c
     join transcript      t
       on c.prereq_id = t.course_code
left join transcript      x 
       on c.course_code = x.course_code
      and t.transcript_id = x.transcript_id
where     t.transcript_id = 'xxxxx'
      and x.course_code is null;

【讨论】:

    【解决方案2】:

    我认为这会起作用,首先从课程中获取不在成绩单中的所有课程,然后根据 prereq_id 匹配 course_code 再次与成绩单进行内部连接(以获得交集)。也许关键字 distinct 不是必需的。

    select distinct course_code from ( select c.* from curriculum as c where c.course_code not in ( select t.course_code from transcript as t where t.CWID = 'C38475920') ) as c2 inner join transcript t2 on t2.course_code = c2.Prereq_ID;

    【讨论】:

    • 感谢您的回复!尽管 #1248 它给出了一个错误 - 每个派生表都必须有自己的别名。看起来您提供的代码是正确的
    • 还需要加上where t.cwid条件。
    • @DelB95 已添加别名,请再次查看。
    • 我必须将 course_code 更改为 c2.course_code 才能运行。可悲的是,返回的课程具有学生尚未满足的先决条件,它将返回学生已经学习过的课程。我感谢您的帮助
    • @DelB95 太糟糕了,我认为查询是正确的。 (我仍然认为是)如果您愿意,可以投反对票。
    猜你喜欢
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    相关资源
    最近更新 更多