1、简单的结果集联合
UNION运算符要放置在两个查询语句之间,只要用UNION操作符连接这两个查询语句就可以将两个查询结果集联合为一个结果集
SQL语句如下:
SELECT FNumber,FName,FAge FROM
T_Employee
UNION
SELECT FIdCardNumber,FName,FAge FROM
T_TempEmployee
UNION可以连接多个结果集,就像“+”可以连接多个数字一样简单,只要在每个结果
集之间加入UNION即可,比如下面的SQL语句就连接了三个结果集:
SELECT FNumber,FName,FAge FROM
T_Employee
WHERE FAge<30
UNION
SELECT FIdCardNumber,FName,FAge FROM
T_TempEmployee
WHERE FAge>40
UNION
SELECT FIdCardNumber,FName,FAge FROM
T_TempEmployee
WHERE FAge<30
2、联合结果集的原则
联合结果集不必受被联合的多个结果集之间的关系限制,不过使用UNION仍然有两个基本的原则需要遵守:一是每个结果集必须有相同的列数;二是每个结果集的列必须类型相容。
首先看第一个原则,每个结果集必须有相同的列数,两个不同列数的结果集是不能联合在一起的
SELECT FNumber,FName,FAge,FDepartmentFROM T_Employee
UNION
SELECT FIdCardNumber,FName,FAge FROM
T_TempEmployee //错误!因为第一个结果集返回了4列数据,而第二个结果集则返回了3列数据,数据库系统并不会用空值将第二个结果集补足为4列
SELECT FNumber,FName,FAge,FDepartmentFROM T_Employee
UNION
SELECT FIdCardNumber,FName,FAge,'临时工,不属于任何一个部门'FROM
T_TempEmployee //使用常量字段将第二个结果集的与FDepartment对应的字段值设定为“临时工,不属于任何一个部门”就可以执行成功
联合结果集的第二个原则是:每个结果集的列必须类型相容,也就是说结果集的每个对应列的数据类型必须相同或者能够转换为同一种数据类型。比如下面的SQL语句在MYSQL中可以正确的执行
SELECT FIdCardNumber,FAge,FNameFROM T_TempEmployee
UNION
SELECT FNumber,FName,FAgeFROM T_Employee //到MYSQL将FAge转换为了文本类型,以便于与FName字段值匹配。不过这句SQL语句在MSSQLServer、Oracle、DB2中执行则会报出类似如下的错误信息:表达式必须具有与对应表达式相同的数据类型。
3、UNION ALL
默认情况下,UNION运算符合并了两个查询结果集,其中完全重复的数据行被合并为了一条。如果需要在联合结果集中返回所有的记录而不管它们是否唯一,则需要在
UNION运算符后使用ALL操作符,比如下面的SQL语句:
SELECT FName,FAge FROM T_Employee
UNION ALL
SELECT FName,FAge FROM T_TempEmployee
//返回正式员工与临时员工所有成员的信息(不管他们信息是否重复)
4、联合结果集应用举例
联合结果集在制作报表的时候经常被用到,使用联合结果集我们可以将没有直接关系的数据显示到同一张报表中。使用UNION运算符,只要被联合的结果集符合联合结果集的原则,那么被连接的两个SQL语句可以是非常复杂,也可以是非常简单的。
//员工年龄报表,要求查询员工的最低年龄和最高年龄,临时工和正式员工要分别查询
SELECT '正式员工最高年龄',MAX(FAge) FROM T_Employee
UNION
SELECT '正式员工最低年龄',MIN(FAge) FROM T_Employee
UNION
SELECT '临时工最高年龄',MAX(FAge) FROM T_TempEmployee
UNION
SELECT '临时工最低年龄',MIN(FAge) FROM T_TempEmployee
//正式员工工资报表,要求查询每位正式员工的信息,包括工号、工资,并且在最后一行加上所有员工工资额合计。
SELECT FNumber,FSalary FROM T_Employee
UNION
SELECT '工资合计',SUM(FSalary) FROM T_Employee
//列出员工姓名,要求列出公司中所有员工(包括临时工)的姓名,将重复的姓名过滤掉
SELECT FName FROM T_Employee
UNION
SELECT FName FROM T_TempEmployee
//分别列出正式员工和临时工的姓名,要求分别列出正式员工和临时工的姓名,要保留重复的姓名。
MYSQL、MSSQLServer:
SELECT '以下是正式员工的姓名'
UNION ALL SELECT FName FROM T_Employee
UNION ALL SELECT '以下是临时工的姓名'
UNION ALL SELECT FName FROM T_TempEmployee
Oracle:
SELECT '以下是正式员工的姓名' FROM DUAL
UNION ALL SELECT FName FROM T_Employee
UNION ALL SELECT '以下是临时工的姓名' FROM DUAL
UNION ALL SELECT FName FROM T_TempEmployee
DB2:
SELECT '以下是正式员工的姓名' FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT FName FROM T_Employee
UNION ALL SELECT '以下是临时工的姓名' FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT FName FROM T_TempEmployee
以上摘自《程序员的SQL金典》