MySQL 数据库聚合查询和联合查询操作

目录
  • 1. 插入被查询的结果
  • 2. 聚合查询
    • 2.1 介绍
    • 2.2 聚合函数
    • 2.3 group by 子句
    • 2.4 having
  • 3. 联合查询
    • 3.1 介绍
    • 3.2 内连接
    • 3.3 外连接
    • 3.4 自连接
    • 3.5 子查询
    • 3.6 合并查询

1. 插入被查询的结果

语法:

insert into 要插入的表 [(列1, ..., 列n)] select {* | (列1, ..., 列n)}from 要查询的表

上述语句可以将要查询的表的某些列插入到新的表中对应的某些列

示例1:student1 表(只包含 id 和 name 字段,且该表已经插入内容)的内容全部插入到 student2 表(只包含 id 和name 字段,该表尚未插入内容)中

示例2: 将 student1 表(只包含 id 和 name 字段,且该表已经插入内容)的字段 name 插入到 student2 表(只包含 id 和name 字段,该表尚未插入内容)中

2. 聚合查询

2.1 介绍

聚合查询:是指对一个数据表中某个字段的数据进行部分或者全部统计查询的一种方式(即是在行的维度进行合并的查询)。比如所有全部书的平均价格或者是书籍的总数量等等,在这些时候就会使用到聚合查询这种方法。

2.2 聚合函数

聚合查询可以使用以下常用聚合函数,这些聚合函数就相当于 SQL 提供的“库函数”

补充:

  • 当只针对某列进行行数的查询时,如果某行的值为 null,则查询结果不计算这行
  • 对数据进行求和时,数据类型必须为数字,字符串和日期都无法求和
  • 如果语法没有错误,但是出现运行时错误则会报出警告 warnings,此时可以通过 show warnings SQL 语句查看警告信息

接下来以表名为 exam_result,具体数据如下的表,进行示例展示

id name chinese math english
1 唐三藏 67.0 98.0 56.0
2 孙悟空 87.5 78.0 77.0
3 猪悟能 88.0 98.5 90.0
4 曹孟德 82.0 84.0 67.0
5 刘玄德 55.5 85.0 45.0
6 孙权 70.0 73.0 78.5
7 宋公明 null null null

示例1: 返回查询到的数据的行数

示例2: 返回查询到的列为 chinese 数据的行数

示例3: 返回查询到的语文成绩的总和

示例4: 返回查询到的各科成绩的平均值

示例5: 返回总成绩的最高值

示例6: 返回总成绩的最低值

2.3 group by 子句

使用前面的聚合函数,实际上是把该表中的所有行结合起来。但还可以使用 group by 来进行分组聚合(在 group by 后面加上指定列名,那么该列中值相同的就将分成一组)

接下来我们将对表名为 emp,数据如下的表进行示例展示

id name role salary
1 张三 开发 10000
2 李四 开发 11000
3 王五 测试 9000
4 赵六 测试 12000
5 田七 销售 7000
6 魔王 老板 50000

示例1: 查看各个岗位的平均薪资

示例2: 查看各个岗位的平均、最高、最低薪资

2.4 having

如果使用 group by 子句进行分组以后,需要对分组结果再进行条件过滤,这时就不能使用 where 语句了,而是使用 having 语句

注意:

  • where 语句是在分组之前进行筛选
  • having 语句是在分组之后进行筛选
  • where 语句和 having 语句可以同时使用

示例1: 查询薪资大于10000的岗位

示例2: 排除张三薪资后,薪资大于10000的岗位

3. 联合查询

3.1 介绍

联合查询:是可合并多个相似的选择查询的结果集。 也就是进行多表查询,其核心思想是使用了笛卡尔积

笛卡尔积思想:

使用笛卡尔积的思想,其实就是把两个表的结果进行一个排列组合,接下来我们将两个表 A、B 通过笛卡尔积的思想得到一个新的表 C

学生表 A:

学号 姓名 班级id
1 张三 2001
2 李四 2001
3 王五 2002

班级表 B:

班级id 班级名
2001 高二(1)班
2002 高二(2)班

新表 C:

学号 姓名 班级id 班级id 班级名
1 张三 2001 2001 高二(1)班
1 张三 2001 2002 高二(2)班
2 李四 2001 2001 高二(1)班
2 李四 2001 2002 高二(2)班
3 王五 2002 2001 高二(1)班
3 王五 2002 2002 高二(2)班

补充:

  • 笛卡尔积得到的结果任然是一个表
  • 该表的列数,是两张表的列数之和
  • 该表的行数,是两张表的行数之积

通过新得到的 C 表,我们就可以将 A、B 两张表联系起来,而联系的纽带在上面的示例中就是班级id。到此时,虽然将两个表联系起来了,但是不是新表中的每条数据都是合理的,例如第2行的信息其实就是不正确的。因此将两表联系起来后,还需要加上一些条件的限制,如 A 和 B 表的班级id应该相同,此时就可以得到一个数据更合理的表 D

新表 D:

学号 姓名 班级id 班级id 班级名
1 张三 2001 2001 高二(1)班
2 李四 2001 2001 高二(1)班
3 王五 2002 2001 高二(2)班

此时我们就可以进行一个多表查询

注意:

联合查询由于使用了笛卡尔积,那么新表的行数就是所有表联合的乘积。因此使用联合查询结果的数据可能很大,要谨慎使用

以下示例都是通过下面 SQL 语句建的表来进行操作学习的,如果你想在后面的内容进行操作,可以直接复制使用

drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;

create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));

create table student (id int primary key auto_increment, sn varchar(20),  name varchar(20), qq_mail varchar(20) ,
        classes_id int);

create table course(id int primary key auto_increment, name varchar(20));

create table score(score decimal(3, 1), student_id int, course_id int);

insert into classes(name, `desc`) values
('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2019级3班','学习了中国传统文学'),
('自动化2019级5班','学习了机械自动化');

insert into student(sn, name, qq_mail, classes_id) values
('09982','黑旋风李逵','xuanfeng@qq.com',1),
('00835','菩提老祖',null,1),
('00391','白素贞',null,1),
('00031','许仙','xuxian@qq.com',1),
('00054','不想毕业',null,1),
('51234','好好说话','say@qq.com',2),
('83223','tellme',null,2),
('09527','老外学中文','foreigner@qq.com',2);

insert into course(name) values
('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');

insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),
-- 白素贞
(33, 3, 1),(68, 3, 3),(99, 3, 5),
-- 许仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-- 不想毕业
(81, 5, 1),(37, 5, 5),
-- 好好说话
(56, 6, 2),(43, 6, 4),(79, 6, 6),
-- tellme
(80, 7, 2),(92, 7, 6);

3.2 内连接

语法:

-- 方法一:
select 展示的列名 from 表1 [表1别名],表2 [表2别名] where 连接条件;

-- 方式二:使用 [inner] join on
select 展示的列名 from 表1 [表1别名] [inner] join 表2 [表2别名] on 连接条件;

补充:

  • 使用多表查询时,由于有多个表,所以使用其中的列,方式为:表名.列名
  • 可以使用 表名 别名 的方式,将表名起一个别名使用
  • 使用 [inner] join on 方式,如果省略 inner,则默认内连接

示例1: 查询许仙同学每门课的成绩

示例2: 查询每个同学的总成绩

示例3: 查询每个同学每门课的成绩

3.3 外连接

外连接:分为左外连接和右外连接。如果使用联合查询,左侧的表完全显示就是用了左外连接;右侧的表完全显示就是用了右外连接

外连接其实和内连接差不多,都是使用了笛卡尔积。内连接是针对的两个表中的每一条数据都是一一对应的,那怎么就不是一一对应了呢?例如下面两个表 A、B

A 表:

id name
1 张三
2 李四
3 王五

B 表:

student_id score
1 90
2 80
4 70

我们发现经过笛卡尔积后建立的新表时,A 表的 id 为3的记录和 B 表中没有对应的数据,B 表中 student_id 为4的记录和 A 表中也没有对应的数据,因此这两个表就不能使用内连接的方式去查询,要使用外连接

如果使用左连接的方式,新表 C 为:

id name student_id score
1 张三 1 90
2 李四 2 80
3 王五 null null

如果使用右连接的方式,新表 D 为:

id name student_id score
1 张三 1 90
2 李四 2 80
null null 4 70

补充:

  • 当两个表中的数据可以一一对应时,使用外连接和内连接是等价的
  • 除了内连接、左外连接、右外连接,其实还有全外连接,但是 MySQL 中不支持全外连接操作

语法:

-- 左连接,表1完全显示
select 展示的列名 from 表1 [表1别名] [left] join 表2 [表2别名] on 连接条件;

-- 右连接,表2完全显示
select 展示的列名 from 表1 [表1别名] [right] join 表2 [表2别名] on 连接条件;

3.4 自连接

自连接:是指在同一张表中连接自身进行查询,使用自连接其实可以将”行转换成列“来进行操作

为什么自连接可以将行转换成列来进行操作呢?假设有一张表 A

student_id course_id score
1 1 70
1 2 90
1 3 80

如果我想找到原表中 student_id 为1,且其课程2成绩高于课程3的同学的信息时,就是要对行与行之间进行比较,但是一张表是不能进行该操作的

通过对自己进行笛卡尔积之后,得到新的表 B

student_id course_id score student_id course_id score
1 1 70 1 1 70
1 2 90 1 2 90
1 3 80 1 3 80

此时我们发现,如果将原表进行笛卡尔积后,有了两张一样的表,就可以实施行与行之间操作

示例: 查询 Java 成绩高于计算机原理成绩的同学

3.5 子查询

子查询:是指嵌入在其它 SQL 语句中的 select 语句,也叫嵌套查询

分类:

  • 单行子查询:返回一行记录的子查询
  • 多行子查询:返回多行记录的子查询(使用 in 或者 exists)

补充:

  • in 进行多行查询过程: 使用子查询时,先执行子查询,将查询的结果存放在内存里,再执行外层查询,根据内存里的结果进行筛选
  • exists 进行多行查询过程: 先执行外层循环,这样就会得到很多记录,在针对每行记录将它带入到子查询中,符合条件的就保留(exists 就是检测子查询结果是否为空集合)

综上所述:

基于 in 的写法,速度快,适合子查询结果集合比较小的情况(较大内存装不下)
基于 exists 的写法,速度慢,适合子查询结果集合比较大,且外层查询结果数量比较少的情况

示例1: 查询不想毕业同学的同班同学(首先要知道不想毕业同学的班级,然后通过班级筛选学生)

示例2: 查询语文或者英语课程的成绩信息(使用 in)

示例3: 查询语文或者英语课程的成绩信息(使用 exists)

3.6 合并查询

合并查询:是使用集合操作符 union union all 来合并多个 select 的执行结果。使用合并查询时,前后查询的结果集中,字段需要一致

补充:

  • union 操作符不会对结果集的数据进行去重,union all 会进行去重
  • 集合操作符的功能其实和操作符 or 的功能类似,但是如果针对不同的表进行查询,那么 or 就不能使用

示例: 查看 id 小于3,或者课程为 Java 的信息

(0)

相关推荐

  • 详解MySQL 联合查询优化机制

    MySQL 联合查询执行策略. 以一个 UNION 查询为例,MySQL 执行 UNION 查询时,会把他们当做一系列的单个查询语句,然后把对应的结果放入到临时表中,最终再读出来返回.在 MySQL中,每个独立的查询都是一个联合查询,从临时表读取返回结果也一样. 这种情形下,MySQL 的联合查询执行很简单--它将这里的联合查询当做是嵌套循环的联合查询.这意味着 MySQL 会运行一个循环去从数据表读取数据行,然而在运行一个嵌套循环从下一个表读取匹配的数据行.这个过程一直持续,直到找到联合查询中

  • MySQL初学者可以告别分组聚合查询的困扰了

    目录 1.分组查询的原理图 2.group by关键字语法详解 3.一个简单的分组查询的案例 4.分组前筛选和分组后筛选 1)原始表和结果集的概念 2)黄同学支大招 3)案例讲解 5.分组查询(按函数分组) 6.分组查询(按多个字段分组) 7.group by和order by,一对老搭档 8.分组查询的总结 1.分组查询的原理图 对上述原始数据,按照DEPARTMENT_ID(员工id)分组统计SALARY(薪水)的平均值. 上述原理写成代码,应该怎么写呢? select department

  • mysql连接查询、联合查询、子查询原理与用法实例详解

    本文实例讲述了mysql连接查询.联合查询.子查询原理与用法.分享给大家供大家参考,具体如下: 本文内容: 连接查询 联合查询 子查询 from子查询 where子查询 exists子查询 首发日期:2018-04-11 连接查询: 连接查询就是将多个表联合起来查询,连接查询方式有内连接.外连接.自然连接.交叉连接.连接查询使得可以同时查看多张表中数据. 内连接:有条件连接,多个表之间依据指定条件连接,匹配结果是保留符合匹配结果的记录. 外连接:与内连接不同的是不管匹配符不符合都保留,根据外连接

  • 详细聊聊关于Mysql联合查询的那些事儿

    目录 联合查询之union 1. 查询中国各省的ID以及省份名称 2. 湖南省所有地级市ID.名字 3. 用union将他们合并 联合查询之union all 联合查询之inner join 1. 查询湖北省有多少地级市 2. 统计各省地级市的数量,输出省名.地级市数量 3. 查询拥有20个以上区县的城市,输出城市名,区县数量 联合查询之三表联合 1. 区县最多的3个城市是哪个省的哪个市,查询结果包括省名,市名,区县数量 联合查询之left join&right join 查询所有省份和它的城市

  • mysql多表联合查询操作实例分析

    本文实例讲述了mysql多表联合查询操作.分享给大家供大家参考,具体如下: MySQL多表联合查询是MySQL数据库的一种查询方式,下面就为您介绍MySQL多表联合查询的语法,供您参考学习之用. MySQL多表联合查询语法: 复制代码 代码如下: SELECT * FROM 插入表 LEFT JOIN 主表 ON t1.lvid=t2.lv_id select * from mytable,title where 表名1.name=表名2.writer ; mysql版本大于4.0,使用UNIO

  • MySQL聚合查询与联合查询操作实例

    目录 一.聚合查询 1.聚合函数(count,sum,avg...) 2.GROUPBY子句 3.HAVING 二.联合查询((重点)多表) 1.内连接 2.外连接 3.自连接 4.子查询 5.合并查询 总结 一. 聚合查询 1.聚合函数(count,sum,avg...) 常见的统计总数.计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有: 注意最后面都是可以加上where,order by这些语句的,这些聚合函数会根据这些语句的结果集来进行查询 后面最好不要加上limit,因为MyS

  • Mysql数据库性能优化之子查询

    记得在做项目的时候, 听到过一句话, 尽量不要使用子查询, 那么这一篇就来看一下, 这句话是否是正确的. 那在这之前, 需要介绍一些概念性东西和mysql对语句的大致处理. 当Mysql Server的连接线程接收到Client发送过来的SQL请求后, 会经过一系列的分解Parse, 进行相应的分析, 然后Mysql会通过查询优化器模块, 根据该Sql所涉及到的数据表的相关统计信息进行计算分析. 然后在得出一个Mysql自认为最合理最优化的数据访问方式, 也就是我们常说的"执行计划",

  • MySQL 数据库 like 语句通配符模糊查询小结

    MySQL 报错:Parameter index out of range (1 > number of parameters, which is 0)--MySQL 数据库 like 语句通配符模糊查询小结 前言 今天在使用MySQL语句执行增删改查操作时,控制台报出了以下错误:Parameter index out of range (1 > number of parameters, which is 0).翻译过来意思就是:查到结果数据为1,真实值应为0,参数越界,产生错误.如此也就明

  • 为什么Mysql 数据库表中有索引还是查询慢

    目录 前言: 1.字段类型不匹配导致的索引失效 2.被索引字段使用了表达式计算 3.被索引字段使用了内置函数 4.like 使用了 %X 模糊匹配 5.索引字段不是联合索引字段的最左字段 6.or 分割的条件 7.in.not in 可能会导致索引失效 总结 前言: 问题分析: 在进行数据库查询的时候,我们都知道索引可以加快数据查询的效率.但是在实际的业务场景下,经常会遇到即使在表中增加了索引,但是同样还是会出现数据查询慢的问题.这就需要具体分析数据查询慢的具体原因到底是什么了. 首先需要进行确

  • MySQL数据库优化之分表分库操作实例详解

    本文实例讲述了MySQL数据库优化之分表分库操作.分享给大家供大家参考,具体如下: 分表分库 垂直拆分 垂直拆分就是要把表按模块划分到不同数据库表中(当然原则还是不破坏第三范式),这种拆分在大型网站的演变过程中是很常见的.当一个网站还在很小的时候,只有小量的人来开发和维护,各模块和表都在一起,当网站不断丰富和壮大的时候,也会变成多个子系统来支撑,这时就有按模块和功能把表划分出来的需求.其实,相对于垂直切分更进一步的是服务化改造,说得简单就是要把原来强耦合的系统拆分成多个弱耦合的服务,通过服务间的

  • Python连接mysql数据库及简单增删改查操作示例代码

    1.安装pymysql 进入cmd,输入 pip install pymysql: 2.数据库建表 在数据库中,建立一个简单的表,如图: 3.简单操作 3.1查询操作 #coding=utf-8 #连接数据库测试 import pymysql #打开数据库 db = pymysql.connect(host="localhost",user="root",password="root",db="test") #使用cursor

  • Android连接MySQL数据库并进行增删改查操作示例讲解

    1.Android 连接MySQL数据库 public class DBOpenHelper { private static String driver = "com.mysql.jdbc.Driver";//MySQL 驱动 private static String url = "jdbc:mysql://IP:3306/数据库";//MYSQL数据库连接Url private static String user = "root";//用

  • Vue项目通过node连接MySQL数据库并实现增删改查操作的过程详解

    目录 Vue项目通过node连接MySQL数据库 1.创建Vue项目 2.下载安装需要的插件 3.在项目中创建server文件夹,用于搭建本地服务器 4.Vue项目访问接口获取数据 数据表的增删改查操作 1.服务器配置 2.前端配置 页面样式 总结 Vue项目通过node连接MySQL数据库 1.创建Vue项目 vue create 项目名 Vue项目创建的详细步骤,有需要的可移步这里 2.下载安装需要的插件 下载express npm install express 下载cors,用于处理接口

  • python的mysql数据库建立表与插入数据操作示例

    本文实例讲述了python的mysql数据库建立表与插入数据操作.分享给大家供大家参考,具体如下: mysql数据库建立表 一 代码 import pymysql # 打开数据库连接 db = pymysql.connect("localhost","root","root","db_test01" ) # 使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() # 使用 exec

随机推荐