MySQL 中 union 的用法

union 用法

在开发过程中常常需要合并两条语句或者多条语句的结果,这就需要用到 union 。语法为 sql1 union sql2。具体内容如下:

  1. 在不使用 or 和 between ... and 的情况下查出价格低于 100 元和价格高于 4000 的商品。

    使用之前的学习内容可能需要两条语句:

    select goods_id,goods_name,shop_price from goods where shop_price < 100;
    
    select goods_id,goods_name,shop_price from goods where shop_price > 4000;
    

    用 union 可以将两条语句连接起来:

    select goods_id,goods_name,shop_price from goods where shop_price < 100 union select goods_id,goods_name,shop_price from goods where shop_price > 4000;
    
  1. union 是合并结果集,不区分源自哪张表。例如从用户留言中取出数据:

    select user_name,msg_content,msg_time from ecs_feedback where msg_status=1;
    
    select user_name,content as msg_content,add_time as msg_time from ecs_comment where status=1;
    

    再合并结果即可:

    select user_name,msg_content,msg_time from ecs_feedback where msg_status=1 union select user_name,content as msg_content,add_time as msg_time from ecs_comment where status=1;
    
  1. 如果两次列的名称不一样,也是可以取出来的,但是列名会一第一次的为准

    select user_name,msg_content,msg_time from ecs_feedback where msg_status=1 union select user_name,content ,add_time from ecs_comment where status=1;
    
    union 列名不同的情况.jpg
  1. union 就像是将两张表合在一起,所以要求结果集中列的数量一致即可,列的类型不一致的则会以前一句的为准,但是这样可能会造成数据的丢失,都是二进制值转成的,数据类型只是在存储的时候区分。
  1. union 后的结果可以再次排序,把前面的结果看成一个结果集即可,例如:

    select goods_id,goods_name,shop_price from goods where shop_price < 100 union select goods_id,goods_name,shop_price from goods where shop_price > 4000 order by shop_price desc;
    

    如果对内层进行排序,例如:

    (select goods_id,goods_name,shop_price from goods where shop_price < 100 order by shop_price desc) union (select goods_id,goods_nameame,shop_price from goods where shop_price > 4000 order by shop_price desc);
    

    结果顺序反而是乱的:

    union 前内层对结果集排序.jpg

因为,使用 union 时内层的 order by 在执行期间如果单独使用没有影响结果集只是排序就被 MySQL 的代码分析器优化了

  1. 使用 union 筛选出第三个栏目下价格前三高的产品和第四个栏目下价格前两高的产品:

    (select goods_id,goods_name,shop_price from goods where shop_price < 100 order by shop_price desc limit 3) union (select goods_id,goods_name,shop_price from goods where shop_price > 4000 order by shop_price desc limit 2);
    

    此时的操作就能正确返回:

    union 连接前同时使用 order by 和 limit.jpg

因为此时 limit 会对结果集产品影响,筛选出来的数据变少了,所以并没有被优化掉

  1. 如果使用 union 的结果有重复,即每列的值都相同,则会过滤到相同的行,最简单的例子就是把相同的两条语句用 union 连接:

    (select goods_id,goods_name,shop_price from goods where shop_price < 100 order by shop_price desc limit 3) union (select goods_id,goods_name,shop_price from goods where shop_price < 100 order by shop_price desc limit 3);
    

    使用 union all 则不会去重:

    (select goods_id,goods_name,shop_price from goods where shop_price < 100 order by shop_price desc limit 3) union all (select goods_id,goods_name,shop_price from goods where shop_price < 100 order by shop_price desc limit 3);
    

练习

有如下了两张表:

union 练习题.jpg

现需要将合并,其中 id 相同的行中 num 相加,id 不同的 num 不变,返回合并后的表

由于表中部分行的 id 不同,使用左连接,会很麻烦,而且还可能会丢行。可以使用 union :

select * from ta union all select * from tb;

先将两张表用 union 连起来,并看成一张表,然后使用 group by 分组求和即可:

select id,sum(num) from (select * from ta union all select * from tb) as tmp group by id;

你可能感兴趣的:(MySQL 中 union 的用法)