union 合并2两或多条语句的结果
语法:sql1语句 union sql2语句
一、例题
1.1、例题1
题目:查处商铺中价格小于30,大于4000的商品。要求不能用or。其中一个解法,就是用两个sql语句查询得到两个表,然后再用union即可。结果如下:

问1:能否从两张表查询,然后union呢?
答:当然可以了,上面不就是么(两个sql结果就当成两个表)
1.2、例题2
题目:上一篇文章中的商城的留言板项目
解法:同样按照上面解法,sql查询得到feedback表跟comment表的结果,然后再合并即可。如下:

问2:对于上图项目,是通过让列名一致(用as起的别名让两个表的字段一样)得到的结果,
那么不加这个as怎么用呢(两个表中列名称不一样是否还能用union)?
答:可以,如下图:

按照结果,我们发现,并没有报错(说明健壮性可以),并且列名以第一个表的为准。
问3:union满足什么一个条件就可以用?
答:只要结果集中的列数一致就可以。
问4:列的类型不一致,可以合并吗?
答:语法上可以(见同理上题)。只不过意义不大。如下:

可见没有什么意义而已。
问5:union后的结果集能否再排序?
答:能

1.3、union与order by
1.3.1、内层order by 对内层结果集没有影响
例题3:用union取出第四个和第五个栏目的商品,并按价格升序排列。
错误示例:sql1得到第四个栏目然后order by,sql2得到第5个栏目,然后order by,最后再union。

按理说,sql1跟sql2都用了降序排列,但是却没有发挥作用???
怎么回事?
举个例子:在新兵入伍前,以村为单位按照高矮排序列队,进了部队以后,还要再次按照高矮排序。那么之前的内部排序就没有意义了。
如果外层语句还会对最终结果再次排序(虽然这里没有),此时内层语句的排序,就没有意义了。此时内层排序在sql代码执行之前,就被优化掉了。也就是不执行了。
尽管这里外层也没有对结果集再次排序,但是一样把内层的order by给优化掉了,因此以后用的时候需要注意。
正确答案:sql1得到第四个栏目,sql2得到第五个栏目,然后union,最后再加上order by。此时,order by会对最终结果集排序了。
问5:那么是不是所有的内层order by都是被判定为无意义并且不执行的呢?
答:不一定。
1.3.2、例题4:内层order by 对最终结果集有影响
查出:第三栏目下价格前3高的商品,与第四栏目下前两高的商品。用union来完成。

为此,我们先查出第三栏目前3高的商品,然后再查出第四栏目下前4高的商品。

再把上面的两个sql语句用union连接起来(注意,要把order by用小括号扩住,不然最后一个order by 会被理解为对所有结果进行排序了)

这时我们发现,内层的order by发挥了作用。因为这里用了limit,此时order by 会对最终的结果集造成影响,也就是说有意义了。因此,就不能忽略了。
1.3.3、总结
- 当内层的order by单独使用,对最终结果集没有影响时,在sql执行期间就会被优化掉了。
- 当内层order by 必须能够影响结果集的时候,才会有意义。
比如配合limit使用。
1.4、如果union结果有重复怎么办
也就说,如果最终结果有n行,并且所有的列,值都一样,怎么办?
这种情况是比较常见的,默认会去重。
如果不想去重,可以用union all来连接两个sql语句。
注意,这里的所有的列跟值完全相同,才会被覆盖。否则是不会被覆盖的。比如:

下面表中尽管表中的id名称b,d相同,但是值不相同,因此union以后不会被去重的。而c的值是相同的,因此执行了去重操作。只留下一个c。

网友评论