SQL中的集合运算有必要存在的几个例子

来源:互联网 发布:股票数据怎么看 编辑:程序博客网 时间:2024/04/28 04:20

原文地址:http://mis.blogbus.com/logs/11754651.html

 

原来集合运算在删选条件为非唯一属性时才显的那么重要

 

-------------------------------------

--  SQL集合运算——查询的差集      --

-------------------------------------

--求没有选择课号为‘c01’的学生学号

 

/*以下语句不正确,原因是cid不是独立主键,并不能函数决定sid

意味着选择了'c01'的某一sid,可能会同时选择非'c01'的其他cid

因此,并不能通过仅排除'c01',而将所有的曾选择过'c01'的该sid排除在外。

该查询的目标范围将比实际的大。

*/

 

select sid from learning

  where cid<>'c01'

 

/*正确语句*/

 

select sid from learning

  except (

    select sid from learning where cid='c01'

  )

 

--求没有选择课号为‘c01’的学生的学号和课号

 

/*不正确。因为sidcid的同时存在于子查询中,使得要减去的部分将比原来的小,

排除了该sid同时选择其他cid而被排除的可能性。其结果范围将比没有cid的大。

*/

 

select sid,cid from learning

  except (

    select sid,cid from learning where cid='c01'

  )

 

--正确:

 

select sid,cid from learning

  where sid in (

    select sid from learning

      except (

        select sid from learning where cid='c01'

      )

  )

 

-------------------------------------

--  SQL集合运算——查询的交集      --

-------------------------------------

--求同时选了课号为'c01''c02'的学生学号

 

/*以下语句不正确。其结果将是空值,因为一个属性在一个元组中只能有一个值,不会有两个值。

select运行时只会一行一行地(逐个元组)进行,不会跨行进行比较。

*/

 

select sid from learning where cid='c01' and cid='c02'

 

/*以下语句正确:*/

 

select sid from learning where cid='c01'

  intersect (

    select sid from learning where cid='c02'

  )

 

/*以下语句正确:通过自连接将cid的一个属性,变成两个名义属性,再逐行进行比较:*/

 

select l1.sid from learning l1,learning l2

  where l1.sid=l2.sid and l1.cid='c01' and l2.cid='c02'

 

--问题:求同时选了课号为'c01'‘c02’的学生学号和课号。

 

-------------------------------------

--  SQL集合运算——查询的并集      --

-------------------------------------

--求计算机系学生的学号和选了'c03'课程且成绩在分以上的学生学号

 

select sid from student where department='计算机系'

  union (

    select sid from learning

      where cid='c03' and score>80

  )

 

--分解分析,两个子查询自动将重复出现的记录合并

 

select sid from student where department='计算机系'

select sid from learning

      where cid='c03' and score>70

原创粉丝点击