javazxy

写sql时我们经常会遇到需要把从多张表查询的集果集进行合并。这时就用到了union。使用union或union all 时一定要保证查询的列的一致性 。不然sql会报错。字段不一致的话可以用单引号来占位。

例:

SELECT T102.CI_ID AS RES_ID,
       T102.CITYPE_ID AS RESTYPE_ID,
       T102.ASSET_NUMB AS RES_CODE,
       \'\' AS RES_E_NAME,
       T102.CI_NAME AS RES_NAME,
       \'\' AS APPNAME_NAME,
       \'\' AS ORIGINAL_ID,
       T102.ASSET_BRAND AS BRAND_ID,
       T102.ASSET_BRAND_NAME AS BRAND_NAME,
       T102.SERIES AS SERIES_ID,
       T102.SERIES_NAME AS SERIES_NAME,
       T102.MODEL AS SPECMODEL_ID,
       T102.MODEL_NAME AS SPECMODEL_NAME,
       T102.NETWORK AS SECZONE_ID,
       T102.INSTALSITE_NAME AS COMPUTERROOM_NAME,
       T102.INSTALSITE AS COMPUTERROOM_ID,
       T102.CABINET_NO AS CABINET_ID,
       T102.CABINET_NO_NAME AS CABINET_NAME,
       \'\' AS RES_GRADE,
       \'\' AS IPV4_DESC,
       \'\' AS BG_ID,
       T102.RUN_CORP_CODE AS BC_ID,
       T102.REMARKS AS RES_DESC,
       T102.ENABLED_STATUS,
       T102.DELETED_FLAG,
       \'\' AS OSTYPE_ID,
       \'\' AS OS_VERSION_NO,
       T102.CREATED_AT,
       T102.UPDATED_AT,
       T102.DELETED_AT
  FROM CI_T10203 T102
 WHERE T102.DELETED_FLAG = \'N\' --磁带库
UNION ALL
SELECT T102.CI_ID AS RES_ID,
       T102.CITYPE_ID AS RESTYPE_ID,
       T102.ASSET_NUMB AS RES_CODE,
       \'\' AS RES_E_NAME,
       T102.CI_NAME AS RES_NAME,
       \'\' AS APPNAME_NAME,
       \'\' AS ORIGINAL_ID,
       T102.ASSET_BRAND AS BRAND_ID,
       T102.ASSET_BRAND_NAME AS BRAND_NAME,
       T102.SERIES AS SERIES_ID,
       T102.SERIES_NAME AS SERIES_NAME,
       T102.MODEL AS SPECMODEL_ID,
       T102.MODEL_NAME AS SPECMODEL_NAME,
       T102.NETWORK AS SECZONE_ID,
       T102.INSTALSITE_NAME AS COMPUTERROOM_NAME,
       T102.INSTALSITE AS COMPUTERROOM_ID,
       T102.CABINET_NO AS CABINET_ID,
       T102.CABINET_NO_NAME AS CABINET_NAME,
       \'\' AS RES_GRADE,
       \'\' AS IPV4_DESC,
       \'\' AS BG_ID,
       T102.RUN_CORP_CODE AS BC_ID,
       T102.REMARKS AS RES_DESC,
       T102.ENABLED_STATUS,
       T102.DELETED_FLAG,

       \'\' AS OSTYPE_ID,
       \'\' AS OS_VERSION_NO,
       T102.CREATED_AT,
       T102.UPDATED_AT,
       T102.DELETED_AT

  FROM CI_T10204 T102
 WHERE T102.DELETED_FLAG = \'N\'

下面就来说明union和union all的区别

准备一张测试数据表。注意mysql中的varchar在oracle中是varchar2

drop table if exists student;
create table student
(
    id int primary key,
    name varchar2(50) not null,
    score number not null
);
insert into student values(1,\'Aaron\',78);
insert into student values(2,\'Bill\',76);
insert into student values(3,\'Cindy\',89);
insert into student values(4,\'Damon\',90);
insert into student values(5,\'Ella\',73);
insert into student values(6,\'Frado\',61);
insert into student values(7,\'Gill\',99);
insert into student values(8,\'Hellen\',56);
insert into student values(9,\'Ivan\',93);
insert into student values(10,\'Jay\',90);
commit;
select * from student where id < 4
union
select * from student where id > 2 and id < 6
--查询结果为

1    Aaron    78
2    Bill     76
3    Cindy    89
4    Damon    90
5    Ella     73

select * from student where id < 4
union all
select * from student where id > 2 and id < 6
--查询结果为

1    Aaron    78
2    Bill    76
3    Cindy    89
3    Cindy    89
4    Damon    90
5    Ella    73

由此可以看出union和union all的区别在于对重复数据的处理。

  union 在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的集果集进行排序运算,删除重复的记录再返回结果集。实际使用时大部分是不会产生重复的记录。

  union all只是简单的将两个结果合并就返回。如果返回的结果集中有重复的数据,那么返回的结果集中就包含有重复数据。

  从性能上讲union all 要比union快很多,它没有排序去重的耗时。如果表数据量很大,并且可以确定合并的结果集中不会包含重复数据的话。就使用union all.

  我一般使用union all.真出现重复数据了再检查一下。

分类:

技术点:

相关文章: