Sql Server的艺术(五) SQL UNION与UNION JOIN运算符

原文:Sql Server的艺术(五) SQL UNION与UNION JOIN运算符

1、关系的集合运算

集合的3个最普通的运算是并、交和差。对于任意集合R和S(当然,这里的R和S可以是表R和表S),这些运算定义如下。

R并S,R或S或两者中元素的集合。一个元素在并集中只出现一次,即使它在R和S中都存在。

R交S,R和S中都存在的元素的集合。

R差S,在R中而不在S中的元素的集合。注意R差S不同于S差R,后者是在S中而不在R中的元素的集合。
关于交、并、差运算的示意图如图所示。

Sql Server的艺术(五) SQL UNION与UNION JOIN运算符

标准SQL中,可以使用UNION运算符实现集合并的运算,但是没有直接提供集合交和集合差操作,可用其他方法来实现。

2、UNION运算符

<strong>使用UNION运算符执行集合并运算</strong>  <br />   --首先选出CNO=1的学生,作为一个集合,然后在选出SNO=10的学生,作为一个集合,最后对两个集合用UNION,即运算,得到最终结果
    SELECT SNO,SNAME,DNAME FROM dbo.STUDENT WHERE CNO=1 UNION SELECT SNO,SNAME,DNAME FROM dbo.STUDENT WHERE CNO=10 --选择1或10的学生部分信息
    <strong>--注意:如果用UNION,SELECT后的子句不写字段,则结果会出现跟下面语句一样(就是没有消除重复行)
    </strong>--下面两条语句得到的结果是一样的,同样也可以用OR来实现
    SELECT * FROM dbo.STUDENT WHERE CNO=1 UNION SELECT * FROM dbo.STUDENT WHERE CNO=10
    SELECT * FROM dbo.STUDENT WHERE CNO=1 OR CNO=10
  <strong>  --注意:UNION运算符执行集合并运算,自动从结果表中消除重复的行<br />  --使用UNION运算符操作后,要保留重复元组的话,必须在UNION运算符后使用ALL关键字指明(UNION改为UNION ALL)<br />  --参与运算的两个集合必须选择同样数量的列,并且相应的列必须具有相同的类型<br /></strong>
Sql Server的艺术(五) SQL UNION与UNION JOIN运算符
<strong>对不同表不同字段采用UNION运算符,并用ORDER BY子句排序</strong>
    SELECT SNAME,CNO,DNAME FROM dbo.STUDENT WHERE CNO=1 OR CNO=10 UNION SELECT TNAME,CNO,DNAME FROM dbo.TEACHER WHERE CNO=1 OR CNO=10 ORDER BY CNO DESC
Sql Server的艺术(五) SQL UNION与UNION JOIN运算符

由此可见,UNION运算符只要求列的类型匹配即可,而对应的列的列名可以使不同的。

两条SELECT语句的字段都不一样,SQLServer将使用UNION运算中第一条SELECT语句中的列名作为结果表中的列名。

UNION运算符组合起来的SELECT语句中,不能有ORDERBY子句,但是可以放在最后一条SELECT语句后面。

对多表进行UNION运算

SELECT CNO AS 学号 FROM dbo.STUDENT WHERE SSEX='男' UNION SELECT CNO AS 学号 FROM dbo.TEACHER WHERE TSEX='女' UNION SELECT CNO AS 学号 FROM dbo.COURSE WHERE CTIME>20 --所有女同学选修的或者男教师开设的或者学时多于20的课程号

<strong>连接表进行聚合运算<br />   --演示的是内连接,外连接 左右连接,原理一样
</strong>    SELECT t.CNO,COUNT(s.CNO) AS aa FROM dbo.TEACHER AS t INNER JOIN dbo.STUDENT AS s ON t.CNO=s.CNO GROUP BY t.CNO  --学生表中修过这门课程的学生的数目
<strong>多表连接综合运用</strong><br />    SELECT t.TNAME,t.DNAME,c.CNAME,s.SNAME,s.MARK FROM dbo.TEACHER AS t LEFT OUTER JOIN dbo.COURSE AS c ON c.CNO = t.CNO INNER JOIN dbo.STUDENT AS s ON s.CNO = c.CNO ORDER BY t.TNAME

    SELECT s.SNO,s.SNAME,c.CNAME,s.MARK FROM dbo.STUDENT AS s INNER JOIN dbo.COURSE AS c ON c.CNO = s.CNO WHERE c.CNAME='计算机入门'
    UNION
    SELECT s.SNO,s.SNAME,c.CNAME,s.MARK FROM dbo.STUDENT AS s INNER JOIN dbo.COURSE AS c ON c.CNO = s.CNO WHERE c.CNAME='生物工程概论' ORDER BY s.SNO
  • 连接多个表时,我们可以认为他们被连成了一个表。尽管没有创建一个物理表,SQL引擎创建了很多虚拟表,当连接表时,可以在每个表中选择任何一列。
  • 关于连接表的数量问题。连接表的数量取决于具体的数据库管理系统,有的规定为最多25个,有的则没有限制。使用时,我们需要查看具体的数据库运行环境。但要注意的是,连接的表越多,响应的时间就越长。
  • 进行多表连接时,我们要特别注意不要忘记查询条件,特别是连接多个表且记录数目较多时。因为如果不指明连接条件,系统将对多表进行笛卡尔连接,会产生庞大的数据。
  • 根据不同的应用的需求,我们要注意连接方式的选择。

相关推荐