关于查找 “选修了全部课程的学生姓名”题目的理解

首先头脑中有三点概念:

    1 。  EXISTS 子查询找到的提交

            NOT EXISTS 子查询中 找不到的提交

           说明:不要去翻译为存在和不存在,把脑袋搞晕。

  2 。 建立程序循环的概念,这是一个动态的查询过程。如 FOR循环 。

  3 。 Exists执行的流程Exists首先执行外层查询,再执行内存查询,与IN相反。 流程为首先取出外

层中的第        一  元组, 再执行内层查询,将外层表的第一元组代入,若内层查询为真,即有结果

时。返回外层表中的第一元 组,接着取出第二元组,执行相同的算法。一直到扫描完外层整表 。

         for(int i =0;  i<>EOFout;i++)

                 {

                     for (int j = 0 ; j<EOFint,j++)

                }

然后再来看一个例子: 三张表  学生表student (Sno,Sname),  课程表course (Cno,Cname) 选课表SC

(Sno,Cno)

要求查询出 :选修了全部课程的学生姓名

我的思路:

首先学生的选课信息存在于SC表中, 要想知道某个学生是否选修了全部课程,至少我们需要知道一共有

几门课程,这是首要的条件。其次,学生选修了与否,我们又要扫描SC全表,统计出选修了所有课程的

学生号,最后在STUDENT表中根据学生号打出姓名 。

语句如下:  (已测试)

select Sname from student             
 where Sno IN
   (select Sno from SC
      group by Sno     //根据Sno分组,统计每个学生选修了几门课程。如果等于course的总数,就

是我们要找的Sno
     having count(*) = (select count(*) from course ))    //统计course中共有几门课程

另一种思路:

引入:将题目换为 查找学号为 00003 没有选修的科目  

        思路:我们可以将已知学号代入,把每一个科目代入(循环),这将形成1*count(*)种组合。

将这组成作为条件,一一与SC表种进行比对,找不到匹配的我们提交 。

                 select Cname from course  where

                          not exists               //找不到的组合,提交course

                               (select * from SC where course.cno = cno and sno = '00002')

//在SC中匹配

换个题目: 查找没有 没有选修科目的学生姓名

         思路:学号未知 , 科目未知,说明有两个未知变量。应该有两个EXISTS。我们可以扫描

student 和 course

                   共有 s * c 中组合,将这些组合与SC的每一项进行匹配,注意s*c组合已经包含所

有可能。如果全部找

                   到 ,就说明已经选修了全部课程。找不到就说明有课程没选修 。再将没选修的的

提交给上一exists 循

                  环 。若上一

                   exists 不存在的再提交给外循环。

                        select Sname from student
                           where NOT exists        //
                              (select  * from course
                               where NOT exists      //不存在的提交给course
                                (select * from SC where
                                    Sno = student.sno  and cno = Course.Cno))   // 代入两个未知变量

  回头看,就是我们第一个引出的题目:

           选修了全部课程的学生姓名

你可能感兴趣的:(c,算法,测试)