三张表:
student(sid, sname)
book(bid, bname)
borrow(sid, bid)
其中borrow表中与student 和 book之间存在外键关系现在要  查询借阅所有图书的同学
写了一条sql语句select sid, sname
from student
where not exists
 (
select *
from book
where not exists
(
select *
from borrow
where student.sid=sid and book.bid=bid
)
 )
经测试时对的, 但是我不太明白, 求哪位解释一下这条sql, 谢谢!

解决方案 »

  1.   

    这个SQL语句的原理就是:否定之否定就是肯定!
    完全可以简单点实现的:
    select s.sid,s.sname
    from student s, book b, borrow bw
    where s.sid=bw.sid and bw.bid=b.bid
      

  2.   

    楼上的“否定知否定”很对了,不过SQL语句不对吧。
    LZ的是借阅所有书的同学
    1楼的是所有借过书的同学
      

  3.   

    not exists求的是差集,差集包含只属于两个集合中的第一个集合的元素。 
      

  4.   

    先反向检验式理解,假设ID等于aaID同学是借阅了全部的书:则语句变为select aaid, sname
    from student
    where not exists
     (
        select *
        from book
        where not exists
            (
                select *
                from borrow
                where sid=aaID and book.bid=bid
            )
     )有内往外看: select *
                from borrow
                where sid=aaID and book.bid=bid这个语句查询aaID这人借的全部书。
    再看先反向检验式理解,假设ID等于aaID同学是借阅了全部的书:则语句变为
    [code=SQL]
       select *
        from book
        where not exists
     (
       aaID借的全部书
      )查询出aaID没有借的书,如aaID全借了,则查出的记录数0.
    再看:select sid, sname
    from student
    where not exists

      aaID没借的书。
    )若aaID没借的书不存在,则返回真。就把aaID的名字和ID查出来。
    楼主明白了不???
    借楼上:否定之否定。
      

  5.   

    从里向外
    第一步:
    select *
        from book
        where not exists
            (
                select *
                from borrow
                where book.bid=bid
            )
    这句话主要意思为找出没有借阅过的图书第二步:
    select *
        from book
        where not exists
            (
                select *
                from borrow
                where @sid=book.sid and book.bid=bid
            )
    找句话的意思为,出现未借阅图书时,找出那条记录的sid(@sid)第三步:
    select sid, sname
    from student
    where not exists
     (
        select *
        from book
        where not exists
            (
                select *
                from borrow
                where student.sid=sid and book.bid=bid
            )
     )找出不在@sid这个集合内的记录。即借阅了所有图书的sid
      

  6.   

    最外层的not exist是对最里层(student.sid=sid)的否定这样可能好理解点。
      

  7.   

    第二次发的这个,要好些了!谢谢rainsilence
      

  8.   

    select s.sname from student s,borrow b,  book bo where sid=b.sid and b.bid=bo.bid