zoukankan      html  css  js  c++  java
  • MySQL必知必会:组合查询(Union)

     
     

    MySQL必知必会:组合查询(Union)

     阅读约 8 分钟

    本篇文章主要介绍使用Union操作符将多个SELECT查询组合成一个结果集。本文参考《Mysql必知必会》+工作实践融合

    组合查询

    定义

    在大多数开发中,使用一条SELECT查询就会返回一个结果集。如果,我们想一次性查询多条SQL语句,并将每一条SELECT查询的结果合并成一个结果集返回。就需要用到Union操作符,将多个SELECT语句组合起来,这种查询被称为并(Union)或者复合查询。

    组合查询适用于下面两种情境中:

    1. 从多个表中查询出相似结构的数据,并且返回一个结果集

    2. 从单个表中多次SELECT查询,将结果合并成一个结果集返回。

    演示

    我们通过一个简单的示例来认识一下Union组合查询。

    创建一个用户表

    图片描述

    首先分两次查询用户表,然后再组合查询

    select user_id,user_nickname,user_status from yy_user where user_status = 1 // 第一次查询

    图片描述

    select user_id,user_nickname,user_status from yy_user where user_id > 3 // 第二次查询

    图片描述

    第一条SQL查询了user_status=1的用户,第二条查询了user_id > 3的用户

    下面我们组合这两条SQL语句:

    select user_id,user_nickname,user_status from yy_user where user_status = 1 
    UNION
    select user_id,user_nickname,user_status from yy_user where user_id > 3

    图片描述

    这条语句由前面的两条语句组成,通过Union组合了两条SELECT,并且把结果集合并后输出。这条组合查询也可以使用同等where语句来替代:

    select user_id,user_nickname,user_status from yy_user where user_status = 1 or user_id > 3;

    组合查询和Where

    whereUnion在多数情况下都可以实现相同的结果集。where可以实现的语句一定可以使用Union语句来实现。但是反过来就不一定正确了,比如下面将会说到的去重和不去重。

    另外,在单表中使用Unionwhere多条件查询较为复杂。而从多张表中获取数据,使用Union会相对于简单些。

    Union使用规则

    Union有他的强大之处,详细介绍之前,首先明确一下Union的使用注意规则。

    1. Union必须由两条或者两条以上的SELECT语句组成,语句之间使用Union链接。

    2. Union中的每个查询必须包含相同的列、表达式或者聚合函数,他们出现的顺序可以不一致(这里指查询字段相同,表不一定一样)

    3. 列的数据类型必须兼容,兼容的含义是必须是数据库可以隐含的转换他们的类型

    包含重复、去除重复

    我们观察一下上面两条语句,第一条SELECT返回了2条数据;第二条SELECT也返回了2条数据。

    但是Union最终的结果返回了3条数据,而不是4条。mysql在查询结果集中帮我们自动去除了重复的行(重复的行是李四),把两条李四合并了。

    一般情况下这样结果是好的,但是如果需要的情况下,我们可以使用Union All操作符来取消自动合并功能。

    select user_id,user_nickname,user_status from yy_user where user_status = 1 
    UNION ALL
    select user_id,user_nickname,user_status from yy_user where user_id > 3

    图片描述

    这一次mysql没有帮我们去除重复,在查询结果中,我们也看到了两条重复的李四。

    之前我们说过whereUnion的区别,这里Union All可以返回重复的数据,就是where子句完成不了的工作。

    结果排序

    使用Union组合查询时,只能使用一条order by子句对结果集进行排序,而且必须出现在最后一条出现的SELECT语句之后。因为`Union不允许对于部分结果集进行排序,只能针对最终检索出来的结果集进行排序。

    注意:由于在多表组合查询时候,可能表字段并不相同。所以,在对于结果集排序的时候需要使用检索出来的共同字段。

    (select user_id,user_nickname,user_status from yy_user where user_status = 1) 
    UNION ALL
    (select user_id,user_nickname,user_status from yy_user where user_id > 3)
    order by user_id desc

    上面检索的字段user_id必须存在于结果集中。

    多表组合查询

    大型项目中数据经常分布在不同的表,检索的时候需要组合查询出来。多表查询的时候,并不要求两个表完全相同,只需要你检索的字段结构相似就可以。

    我们已经有一张user表,假设搜索时候我们需要将用户昵称和博客文章标题一同混合检索。

    图片描述

    看下上面的posts表,posts_nameuser_nickname类型相同,而posts_iduser_id类型相同,post_statususer_status类型相同。尽管他们的名称不相同。

    我们可以这么来检索:

    select posts_id,posts_name,posts_status from yy_posts
    UNION
    select user_id,user_nickname,user_status from yy_user

    图片描述

    从上面的检索结果能看出,我们将两个表的数据组合了起来。Union检索遇到不一致的字段名称时候,会使用第一条SELECT的查询字段名称,或者你使用别名来改变查询字段名称。

    区分多表

    上一个例子中,我们组合查询了user表和posts表。虽然结果混合在一起没有任何问题,但是当显示到页面的时候,我们需要给用户和文章不同的链接或者其他的区分。所以我们必须确定该条记录来自于哪张表,我们可以添加一个别名来作为表名。

    select posts_id,posts_name,posts_status,'users' as table_name from yy_posts
    UNION
    select user_id,user_nickname,user_status,'posts' as table_name from yy_user

    图片描述

    注意SQL语句中的'users' as table_name。对应的是图片里的table_name,就是我们刚刚添加用于区别表的字段。

  • 相关阅读:
    D. Constructing the Array
    B. Navigation System
    B. Dreamoon Likes Sequences
    A. Linova and Kingdom
    G. Special Permutation
    B. Xenia and Colorful Gems
    Firetrucks Are Red
    java getInstance()的使用
    java 静态代理和动态代理
    java 类加载机制和反射机制
  • 原文地址:https://www.cnblogs.com/taosiyu/p/12069932.html
Copyright © 2011-2022 走看看