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,就是我们刚刚添加用于区别表的字段。

MySQL必知必会:组合查询(Union)的更多相关文章

  1. 《MySQL必知必会》[01] 基本查询

    <MySQL必知必会>(点击查看详情) 1.写在前面的话 这本书是一本MySQL的经典入门书籍,小小的一本,也受到众多网友推荐.之前自己学习的时候是啃的清华大学出版社的计算机系列教材< ...

  2. 《MySQL必知必会》[02] 多表联合查询

    1.基本连接 不同类型的数据,存储在多个表中,而所谓多表连接,就是将多个表联合返回一组输出. 1.1 等值连接 基本的连接方式非常简单,只需要在WHERE子句中规定如何关联即可,如下: SELECT ...

  3. 《MySQL 必知必会》读书总结

    这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter pas ...

  4. mysql必知必会

    春节放假没事,找了本电子书mysql必知必会敲了下.用的工具是有道笔记的markdown文档类型. 下面是根据大纲已经敲完的章节,可复制到有道笔记的查看,更美观. # 第一章 了解SQL## 什么是S ...

  5. 《MySQL必知必会》整理

    目录 第1章 了解数据库 1.1 数据库基础 1.1.1 什么是数据库 1.1.2 表 1.1.3 列和数据类型 1.1.4 行 1.1.5 主键 1.2 什么是SQL 第2章 MySQL简介 2.1 ...

  6. mysql 必知必会总结

    以前 mysql 用的不是很多, 2 天看了一遍 mysql 必知必会又复习了一下基础.  200 页的书,很快就能看完, 大部分知识比较基础, 但还是了解了一些以前不知道的知识点.自己做一个备份,随 ...

  7. 读《MySQL必知必会》我学到了什么?

    前言 最近在写项目的时候发现自己的SQL基本功有些薄弱,遂上知乎查询MYSQL关键字,期望得到某些高赞答案的指点,于是乎发现了 https://www.zhihu.com/question/34840 ...

  8. MySQL必知必会(第4版)整理笔记

    参考书籍: BookName:<SQL必知必会(第4版)> BookName:<Mysql必知必会(第4版)> Author: Ben Forta 说明:本书学习笔记 1.了解 ...

  9. MySQL必知必会1-20章读书笔记

    MySQL备忘 目录 目录 使用MySQL 检索数据 排序检索数据 过滤数据 数据过滤 用通配符进行过滤 用正则表达式进行搜索 创建计算字段 使用数据处理函数 数值处理函数 汇总数据 分组数据 使用子 ...

随机推荐

  1. java程序报错:Unable to open debugger port (127.0.0.1:63959): java.net.SocketException "socket closed",编译过来就是无法打开调试器端口,套接字已关闭

    报错:Unable to open debugger port (127.0.0.1:63959): java.net.SocketException "socket closed" ...

  2. czy的后宫——矩阵快速幂优化DP

    题意 有 n 个位置排成一行,可以放 m 种妹子.每个位置可以放也可以不放,规定某些妹子不能相邻,求方案数. 分析 #include<bits/stdc++.h> using namesp ...

  3. Java知识点汇总-2

    目录 1 变量的作用域 2 二维数组的定义 1 变量的作用域 实例代码: public void fight(String name){ if ("Bean".equals(nam ...

  4. 007_硬件基础电路_RC复位电路中二极管的作用

    --------------------- 作者:碎碎思 来源:CSDN 原文:https://blog.csdn.net/Pieces_thinking/article/details/781110 ...

  5. C#第三章

    一.ImageList:存储图像集合 Images 存储的所有图像 ImageSize 图像的大小 ColorDepth 颜色数 TransparentColor 被视为透明的颜色 先设置ColorD ...

  6. myeclipse2018大括号之前会自动加空格

  7. 第三章 基本的bash shell命令

    1.硬链接:等同于引用了原文件,并未产生新的文件,不同的硬链接共用一个inode 2.符号链接:创建的是一个新文件,新文件指向原文件,因为是不同的文件,所以有不同的inode

  8. [HNOI2004]L语言 字典树 记忆化搜索

    [HNOI2004]L语言 字典树 记忆化搜索 给出\(n\)个字符串作为字典,询问\(m\)个字符串,求每个字符串最远能匹配(字典中的字符串)到的位置 容易想到使用字典树维护字典,然后又发现不能每步 ...

  9. HDU4254 A Famous Game

    luogu嘟嘟嘟 这题刚开始特别容易理解错:直接枚举所有\(n + 1\)种情况,然后算哪一种情况合法,再统计答案. 上述思想的问题就在于我们从已知的结果出发,默认这种每一种情况中取出\(q\)个红球 ...

  10. 如何用Python删除一个文件?

    删除文件 path,删除时候如果path是一个目录, 抛出 OSError错误. remove() 同 unlink() 的功能是一样的 os.remove('a.txt') 如果remove文件夹就 ...