SQL union学习

union和union all都是将多个查询的结果集合并到一张表里。union缺省在合并结果集后消除重复项,union all指定在合并结果集后保留重复项。
union默认用第一个字段进行排序,当然也可以在最后一个结果集里用order by子句排序。

把TEST_T表重新改一下:

drop table test_t;

CREATE TABLE
TEST_T
(
ID NUMBER,
NO NUMBER,
T_NAME VARCHAR2(50),
S_NAME VARCHAR2(50),
SCORE NUMBER
);

insert into TEST_T VALUES(1, 1, 'Peter', '张三', 60);
insert into TEST_T VALUES(2, 2, 'Mary', '李四', 99);
insert into TEST_T VALUES(3, 3, 'Tom', '王五', 76);


–简单的union联合

select id, s_name from test_t union select score, t_name from test_t;

ID S_NAME
1 张三
2 李四
3 王五
60 Peter
76 Tom
99 Mary

//union将两个查询的结果集,联合在了一个表里,虽然这里id表示序号,score表示成绩。。。

–为列定义别名

select id as "1111", s_name as "2222" from test_t union select score as "1111", t_name as "2222" from test_t;

1111 2222
1 张三
2 李四
3 王五
60 Peter
76 Tom
99 Mary

–别名不一样

select id as "1111", s_name as "2222" from test_t union select score as "3333", t_name as "4444" from test_t;

1111 2222
1 张三
2 李四
3 王五
60 Peter
76 Tom
99 Mary

//可以看到别名不一样时,oracle是以第一个表的别名为准

–列的类型不一样

select id, s_name from test_t union select no, score from test_t;

//ORA-01790: expression must have same datatype as corresponding
//id、s_name是number和varchar2型,no、score都是number型,所以会类型不匹配

//如果将第一句后一个查询语句两个列颠倒,也会报这个错

select id, s_name from test_t union select t_name, score from test_t;

//ORA-01790: expression must have same datatype as corresponding
//union只判断字段的类型,原字段的名称是什么无所谓

–修改一下s_name字段的长度

ALTER TABLE test_t MODIFY s_name VARCHAR2(30);

–列类型相同但长度不一样

select id, s_name from test_t union select score, t_name from test_t;

ID S_NAME
1 张三
2 李四
3 王五
60 Peter
76 Tom
99 Mary

//s_name长度是30,t_name长度是50
//正常执行,没有报错,猜测oracle是以长度最大的列的长度为结果

小结:
1)使用union和union all每个结果集提取出来的列的字段类型必须相互对应一致。
2)union因为要进行重复值扫描,所以效率比union all低。

参考资料:http://blog.csdn.net/wanghai__/article/details/4712555/

《SQL union学习》上的3个想法

评论已关闭。