sql的集合操作

原文转自:http://blog.csdn.net/qsyzb/article/details/12560917

SELECT语句的查询结果是元组的集合,所以多个SELECT语句的结果可进行集合操作。

集合操作主要包括并操作UNION、交操作INTERSECT、差操作EXCEPT。

注意,参加集合操作的各查询结果的列数必须相同;对应的数据类型也必须相同。

本示例中的数据表有student,sc,course三个,数据表的具体内容请看:Mysql数据库中的EXISTS和NOT EXISTS

UNION示例:

例子1.1

题目:查询计算机科学系的学生及年龄不大于19岁的学生。

SQL语句:

[sql] view plaincopy
 
  1. SELECT * FROM Student WHERE Sdept='CS' UNION   
  2. SELECT * FROM Student WHERE Sage<=19  

查询结果:

本查询实际上是求计算机系的所有学生与年龄不大于19岁的学生的并集。

与它等效的SQL语句是:

[sql] view plaincopy
 
  1. SELECT * FROM Student WHERE Sdept='CS' OR Sage<=19  

注意:虽然这个两个SQL语句是等效的,但是本质上是不一样的,第一个SQL语句是分别进行两次SELECT然后将结果取并集;第二个SQL语句是直接进行了一次SELECT语句查询。

INTERSECT示例:

MySql语句并不支持INTERSECT,所以只能使用其替代语句

例子2.1

题目:查询计算机科学系中年龄不大于19岁的学生。

对应的SQL语句应该是:

[sql] view plaincopy
 
  1. SELECT * FROM Student   
  2. WHERE Sdept='CS'  
  3. INTERSECT  
  4. SELECT * FROM Student  
  5. WHERE Sage<=19;  


替代的SQL语句:

[sql] view plaincopy
 
  1. SELECT *  
  2. FROM student  
  3. WHERE Sdept = 'CS'  
  4. AND Sage <=19  

查询结果:

例子2.2

题目:查询即选修了课程1又选修了课程2的学生。(就是查询选修课程1的学生集合与选修课程2的学生集合的交集)

对应的SQL语句应该是:

[sql] view plaincopy
 
  1. SELECT Sno FROM SC  
  2. WHERE  Cno='1'  
  3. INTERSECT  
  4. SELECT Sno FROM SC  
  5. WHERE Cno='2';  


替代的SQL语句为:

(使用IN)

[sql] view plaincopy
 
  1. SELECT Sno  
  2. FROM SC  
  3. WHERE Cno = '1'  
  4. AND Sno  
  5. IN (  
  6. SELECT Sno  
  7. FROM SC  
  8. WHERE Cno = '2'  
  9. )  


或者为:

(使用EXISTS)

[sql] view plaincopy
 
  1. SELECT Sno  
  2. FROM SC SCX  
  3. WHERE Cno = '1'  
  4. AND EXISTS (  
  5. SELECT Sno  
  6. FROM SC SCY  
  7. WHERE Cno = '2'  
  8. AND SCX.Sno = SCY.Sno  
  9. )  

查询结果为:

或者为:

(使用JOIN ON)

[sql] view plaincopy
 
  1. SELECT *  
  2. FROM SC SCX  
  3. JOIN SC SCY ON ( SCX.Cno = '1'  
  4. AND SCY.Cno = '2'  
  5. AND SCX.Sno = SCY.Sno )  


EXCEPT操作:

很不幸,MySql也不支持EXCEPT操作,只能使用替代的语句。

例子3.1

查询计算机科学系的学生与年龄不大于19岁的学生的差集。

对应的SQL语句为:

[sql] view plaincopy
 
  1. SELECT * FROM Student WHERE Sdept='CS'  
  2. EXCEPT   
  3. SELECT * FROM Student WHERE Sage<=19;  


也就是查询计算机科学系中年龄大于19岁的学生。

替换语句为:

(直接使用WHERE,不得不说这么做很简单,但是意思上不是很好理解)

[sql] view plaincopy
 
  1. SELECT *  
  2. FROM Student  
  3. WHERE Sdept = 'CS'  
  4. AND Sage >19  


查询结果为:

或者替换语句为:

(使用NOT IN)

[sql] view plaincopy
 
  1. SELECT *  
  2. FROM Student  
  3. WHERE Sdept = 'CS'  
  4. AND Sno NOT  
  5. IN (  
  6. SELECT Sno  
  7. FROM Student  
  8. WHERE Sage <=19  
  9. )  

查询结果为:

或者使用替换语句为:

(使用NOT EXISTS)

[sql] view plaincopy
 
  1. SELECT *  
  2. FROM Student SX  
  3. WHERE Sdept = 'CS'  
  4. AND NOT  
  5. EXISTS (  
  6. SELECT *  
  7. FROM Student SY  
  8. WHERE SY.Sage <=19  
  9. AND SX.Sno = SY.Sno  
  10. )  

查询结果为:

对集合操作结果的排序

ORDER BY子句只能用于对最终查询结果排序,不能对中间结果排序。

任何情况下,ORDER BY子句只能出现在最后;对集合操作结果排序时,ORDER BY子句中用数字指定排序属性。

下面是一种错误的写法

[sql] view plaincopy
 
  1. SELECT * FROM Student  
  2. WHERE Sdept='CS'  
  3. ORDER BY Sno  
  4. UNION  
  5. SELECT * FROM Student  
  6. WHERE Sage<=19  
  7. ORDER BY Sno;  


正确的应该是:

[sql] view plaincopy
 
  1. SELECT * FROM Student  
  2. WHERE Sdept='CS'  
  3. UNION  
  4. SELECT * FROM Student  
  5. WHERE Sage<=19  
  6. ORDER BY 2;  

输出结果:

如果写成:

[sql] view plaincopy
 
  1. SELECT * FROM Student  
  2. WHERE Sdept='CS'  
  3. UNION  
  4. SELECT * FROM Student  
  5. WHERE Sage<=19  
  6. ORDER BY 1;  

输出结果为:

原文地址:https://www.cnblogs.com/jiangwang2013/p/3660608.html