SELECT  S# 
FROM S 
WHERE NOT EXISTS --不存在刘老师的一门课程
 (SELECT * FROM C,T 
  WHERE C.T#=T.T# 
  AND TNAME='LIU'
  AND NOT EXISTS --该学生没有学
(SELECT * FROM SC WHERE SC.S#=S.S# AND SC.C#=C.C#) 
 )
以上是检索选修课程包含liu老师所授全部课程的学生号(注释是老师的解释)。听起来没问题,可是自己还是理解不了。
请问:这个查询语句是如何一步一步查找的?该怎么理解?
请指教,谢谢。

解决方案 »

  1.   

    如果你的数据不存在重复性,这样也许好理解多了。select s# from sc , s , c where SC.S#=S.S# AND SC.C#=C.C# group by s# having count(1) = (select count(1) from t where TNAME='LIU')--上面的字段名也许有错,最好你能提供详细的资料.
      

  2.   

    实际上就是双重否定,参考如下的例.
    现有两张表 
    create table C(C# int,CN varchar) 
    create table SC(S# int,C# int,G int) 表中数据如下 
    C表 
    C#      CN 
    1 厚黑学 
    2 查询基础 
    3 能说 
    4 会道 http://topic.csdn.net/u/20080313/21/acb7f550-8ce7-4352-96dc-4715a0e43287.html?398509657SC表 
    S#      C#      G 
    1 1 1 
    1 3 6 
    2 1 75 
    2 2 55 
    2 3 7 
    2 4 7 
    3 3 77 
    4 1 75 
    4 2 55 
    4 3 7 
    4 4 7 
    6 6 6 
    7 4 7 要求显示出SC表中的C#包含C表中所有的C#的行 即结果是 
    2 1 75 
    2 2 55 
    2 3 7 
    2 4 7 
    4 1 75 
    4 2 55 
    4 3 7 
    4 4 7 -----------------------------------------------
    create table C(C# int, CN varchar(10))
    insert into C values(1, '厚黑学') 
    insert into C values(2, '查询基础') 
    insert into C values(3, '能说') 
    insert into C values(4, '会道') 
    create table SC(S# int, C# int, G int)
    insert into SC values(1 ,1 ,1 )
    insert into SC values(1 ,3 ,6 )
    insert into SC values(2 ,1 ,75) 
    insert into SC values(2 ,2 ,55) 
    insert into SC values(2 ,3 ,7 )
    insert into SC values(2 ,4 ,7 )
    insert into SC values(3 ,3 ,77) 
    insert into SC values(4 ,1 ,75) 
    insert into SC values(4 ,2 ,55) 
    insert into SC values(4 ,3 ,7 )
    insert into SC values(4 ,4 ,7 )
    insert into SC values(6 ,6 ,6 )
    insert into SC values(7 ,4 ,7 )
    goselect * from sc aa where not exists
    (select 1 from  c a left join (select * from sc where s#=aa.s#) b on a.c#=b.c# 
    where  b.c# is null)/*
    S#          C#          G           
    ----------- ----------- ----------- 
    2           1           75
    2           2           55
    2           3           7
    2           4           7
    4           1           75
    4           2           55
    4           3           7
    4           4           7(所影响的行数为 8 行)
    */--------------------------------------------------------------
    --1、取出所有的S#
    select distinct S# from SC
    /*
    S#          
    ----------- 
    1
    2
    3
    4
    6
    7
    (所影响的行数为 6 行)
    */--2、取出所有的S#,C#
    select M.* , C.C# from (select distinct S# from SC) M,C
    /*
    S#          C#          
    ----------- ----------- 
    1           1
    1           2
    1           3
    1           4
    2           1
    2           2
    2           3
    2           4
    3           1
    3           2
    3           3
    3           4
    4           1
    4           2
    4           3
    4           4
    6           1
    6           2
    6           3
    6           4
    7           1
    7           2
    7           3
    7           4
    (所影响的行数为 24 行)
    */--3、按上表找出在sc表不存在的S#,C#,然后只对S#取唯一即可。C#没用了。
    select distinct t.S# from (select M.* , C.C# from (select distinct S# from SC) M,C) t where not exists (select 1 from SC n where n.S# = t.S# and n.C# = t.C#)
    /*
    S#          
    ----------- 
    1
    3
    6
    7
    (所影响的行数为 4 行)
    */--4、从sc表里的S#找出不在上表S#就是你要的结果
    select sc.* from sc where S# not in (select distinct t.S# from (select M.* , C.C# from (select distinct S# from SC) M,C) t where not exists (select 1 from SC n where n.S# = t.S# and n.C# = t.C#))drop table C,SC
      

  3.   

    http://blog.csdn.net/feixianxxx/archive/2009/10/20/4704774.aspx
      

  4.   

    学习,exists我都是会用但是不理解
      

  5.   

    SELECT * FROM C,T 
      WHERE C.T#=T.T# 
      AND TNAME='LIU'
      AND NOT EXISTS            
        (SELECT * FROM SC WHERE SC.S#=某个学生的学号  AND SC.C#=C.C#) 
    结果t:结果是所有刘老师的课程中,排除该学生选的刘老师的课程。外面是个大循环,对于每一行来说,该行的学号就是子查询中的S.S#,
    说对于该行来说,如果结果t为null,则not exists 为true,则该条记录取出,
    反之则过滤掉。
    类似于双重否定等于肯定。