本篇文章内容为;MySQL的复杂查询,针对工作中常见的sql操作,提出自己的意见。

主题为:视图、子查询(包括标量子查询、关联子查询)

首先,我们依旧先进入提问环节:如果我们需要经常性的某列数据进行汇总,有没有什么便捷的方法?

答案是可以使用视图来解决。

比如,我们需要对学生的性别来进行汇总,可以使用创建一个“按性别汇总”的视图,以后方便频繁调用。

那“视图”是什么呢?请看下面的讲解.

目录视图

子查询

标量子查询

关联子查询

视图(View)

我们按照以下导图结构对视图进行介绍:

视图是SQL语句的结果集的可视化表。视图不可以存放数据,存放的是SQL查询语句,它是一张临时表。

1)创建视图

我们打开Navicat-新建查询,在编辑器中输入代码,例如创建一个按性别汇总的视图,并运行:

-- 创建视图CREATE VIEW 按性别汇总(性别,人数) AS SELECT 性别,COUNT(*) FROM student GROUP BY 性别;

在左侧的操作栏中,点击视图,鼠标右键,点击刷新,便成功创建一个视图:

注意的是,视图是临时性的;视图数据会随着原表数据的变化随时更新,保证数据的最新状态;并且,视图不需要保存,可以节省设备存放空间;更值得一提的是,创建好的视图可进行频繁使用,大量提高工作效率。

2)使用视图

视图也是可以被from子句调用的。比如说:

-- 使用视图SELECT * FROM 按性别汇总;

3)删除视图:

删除视图,同样鼠标右键点击我们不需要的视图,然后选择“删除视图”。

子查询子查询(Sub Query)或者说内查询(Inner Query),也可以称作嵌套查询(Nested Query),是一种嵌套在其他 SQL 查询的 WHERE 子句中的查询。

子查询可看作是在select语句中直接写定义的视图;子查询是临时表,SQL语句查询结束它也消失了。

案例:

-- 用子查询来进行性别汇总SELECT 性别,人数 FROM (SELECT 性别,COUNT(*)as 人数 FROM student GROUP BY 性别) AS 按性别汇总;

子查询也可以放到条件where中:

先说一个错误的案例:

-- 找出每个课程里成绩最低的学号/*大白话翻译:按课程号分组,对分组结果查询最低成绩;寻找最低成绩对应的学号;SELECT 课程号,MIN(成绩) FROM score GROUP BY 课程号;SELECT 学号,课程号,成绩 FROM score WHERE 成绩 in ;*/

SELECT 学号,课程号,成绩 FROM score WHERE 成绩 in (SELECT 课程号,MIN(成绩) FROM score GROUP BY 课程号);

系统报错了:

因为使在父查询使用where语句时,子查询只能在有一列的SELECT子句中。而错误的案例中,有两个——课程号,MIN(成绩);我们进行修改:

-- 找出成绩比课程0002的全部成绩中的任一成绩高的学生/*大白话翻译:查找课程0002的全部成绩;某个学生的任一成绩大于刚才的成绩就符合条件;SELECT 成绩 FROM score WHERE 课程号='0002';SELECT 学号,成绩 FROM score WHERE 成绩>ANY;*/

SELECT 学号,成绩 FROM score WHERE 成绩 > ANY(SELECT 成绩 FROM score WHERE 课程号='0002');

-- 找出成绩比课程0002的全部成绩中的全部成绩都高的学生/*大白话翻译:查找课程0002的全部成绩;某个学生的全部成绩大于刚才的成绩就符合条件;SELECT 成绩 FROM score WHERE 课程号='0002';SELECT 学号,成绩 FROM score WHERE 成绩>ALL;*/

SELECT 学号,成绩 FROM score WHERE 成绩 > ALL(SELECT 成绩 FROM score WHERE 课程号='0002');

注意,子查询有以下注意事项:子查询必须被圆括号()括起来;

子查询在使用条件语句时只能在有一列的SELECT子句中;

子查询在where语句中,子查询不可以对all子句进行运算(all 得到的是n行数据);

避免使用多层嵌套子查询,随着子查询越来越多,会难看懂难维护性能差;

养成良好的书写习惯,不要省略子查询的别名;

ORDER BY不能在子查询中使用。

标量子查询

标量子查询是返回结果只有一个单一值的子查询。所以标量子查询可以可比较运算符一起使用。

使用实例来看什么是标量子查询:

-- 查询大于平均成绩学生的学号和成绩/*大白话:得出平均成绩;成绩大于平均成绩就符合条件,对符合条件的学号和成绩汇总;SELECT AVG(成绩) FROM score;SELECT 学号,成绩 FROM score WHERE 成绩 > ;*/

SELECT 学号,成绩 FROM score WHERE 成绩 > (SELECT AVG(成绩) FROM score);

和子查询的案例中不同的是,标量子查询返回的是一个值,比如一个平均值;而上边子查询的案例中返回的是很多值(比如all、any),这就是区别。标量子查询可以与比较运算符、逻辑运算符一起使用。

所以,在使用标量子查询时,一定不能返回多行。

关联子查询

刚才我们的例子,是要求“大于平均成绩学生的学号和成绩”,那如果,我们要想知道“每一科成绩都大于该科平均成绩学生的学号和成绩”该怎么办?

这里就可以使用关联子查询了,实例来看:

-- 每一科成绩都大于该科平均成绩学生的学号和成绩/*大白话:对每一科课程分组,对分组结果计算平均成绩;对每一科对应的学生的成绩比较,大于该科平均成绩的便符合条件SELECT 课程号,AVG(成绩) FROM score GROUP BY 课程号;SELECT 学号,课程号,成绩 FROM score WHERE 成绩> ;*/

SELECT 学号,课程号,成绩 FROM score as s1 WHERE 成绩 >

(SELECT AVG(成绩) FROM score as s2 WHERE s1.课程号=s2.课程号 GROUP BY 课程号);

同样,我们一定要注意,在父查询使用条件语句时,子查询只能在有一列的SELECT子句中;另外,我们需要解释一下,为何“WHERE s1.课程号=s2.课程号”,因为在两次查询中都需从成绩表中获取数据,并通过课程号是否一致来寻找符合条件的学生。

总结

通过以上我们对视图、子查询、标量子查询、关联子查询进行区别:视图:便于频繁使用;

子查询:临时表,但可对返回的多行进行查询;

标量子查询:临时表,对返回的单一值进行查询;

关联子查询:临时表,可在每个组里进行比较查询。

关于用SQL解决业务问题,可以参考上一篇文章,有详细的分析思路和套用公式:一朵云:MySQL数据分析:汇总分析​zhuanlan.zhihu.com

参考

Mysql 修改 复杂的汇总_MySQL数据分析:复杂查询相关推荐

  1. mysql cpu 高 原因 汇总_MySQL CPU 使用率高的原因和解决方法(来自aliyun官方文档)

    用户在使用 MySQL 实例时,会遇到 CPU 使用率过高甚至达到 100% 的情况.本文将介绍造成该状况的常见原因以及解决方法,并通过 CPU 使用率为 100% 的典型场景,来分析引起该状况的原因 ...

  2. mysql修改路径报错_mysql修改数据存储路径报错处理

    Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' 解决?: >>> vim ...

  3. mysql 修改某列数据_mysql修改表某列数据问题

    2012-11-02 回答 下面列出: 1.增加一个字段 alter table user add column new1 varchar(20) default null; //增加一个字段,默认为 ...

  4. mysql修改表结构权限_mysql 修改表结构操作

    mysql 修改表结构操作 使用 [desc 表名]查看表结构 1.mysql > alter table passwd add id int(3) not null auto_incremen ...

  5. mysql修改表结构例子_mysql修改表结构方法实例详解

    本文实例讲述了mysql修改表结构方法.分享给大家供大家参考.具体如下: mysql修改表结构使用ALTER TABLE语句,下面就为您详细介绍mysql修改表结构的语句写法,希望对您学习mysql修 ...

  6. mysql 修改多表数据库_mysql数据库:mysql增删改、单表、多表及子查询

    本文目录: 一.数据增删改 增加数据 insert [into] 表名[(可选字段名)] values(一堆值1),(一堆值2),..... into 可以省略 表名后的字段可以选 如果写了 后面的v ...

  7. mysql 修改字段值语句_mysql修改字段语句

    --------------------------------------------------------- Ta 只分享的内容开始 ------------------------------ ...

  8. mysql 修改列名和属性_mysql增加列修改列名列属性以及删除列

    首先推荐一本初学者的书,一个小册子:<mysql必知必会>简介实用,权威:有点贵,昨天才买的. http://www.2cto.com/ebook/201112/30389.html 正文 ...

  9. mysql修改列名为主键_mysql怎么修改列名为主键?

    mysql修改列名为主键的方法:使用"ALTER TABLE 数据表名 ADD PRIMARY KEY(字段名/列名);"语句设置即可:设置成主键约束的字段/列要确保值不能有重复, ...

最新文章

  1. 不是吧!程序员今年在相亲市场上这么受欢迎?
  2. C++内联函数(inline)
  3. 学Python可以用来干什么?
  4. 计算机管理 如何将c盘,教程:新买的电脑如何把C盘分区成多个盘?
  5. SQL Server Always On可用性组中的数据同步
  6. 生成逼真3D人偶,居然不用3D形状建模,还能学会你的舞步 | 三星CVPR Oral
  7. python开发最受欢迎的十款工具
  8. nginx-配置记录
  9. 计算机网络方向 CCF推荐会议及期刊
  10. Typora上使用Latex语法(持续更新)
  11. 腾讯视频VIP会员,周卡特价9.5元!
  12. 听别人的故事探索属于自己的方法
  13. 瑞萨e2studio(5)----使用UART串口烧写程序到瑞萨芯片
  14. Markdownpad2安装注册
  15. VRF proof极简理解
  16. 计算机软件过期黑屏怎么办,Adobe flashplayer过期怎么办
  17. 一些实用高效的装机软件汇总
  18. 德友圈服务器维护多久,原神蒙德城走一圈要多久
  19. 软件测试新手入门该学什么?最全整理,照着学就对了
  20. 阿里合伙人彭翼捷:每个阶段都给自己找一个目标!

热门文章

  1. C#重点知识详解(一) 选择自 masterall 的 Blog
  2. 解决javah生成c头文件时找不到android类库的问题
  3. 解决GitHub加载和下载慢问题
  4. Java执行main方法,异常为:could not find the main class.program will exit
  5. 解决 maven 项目中加入了 lombok 库后依然报错的问题
  6. 利用axios解决跨域的问题
  7. 如何在Swift中串联或合并数组?
  8. 无法在终端中显示Git树
  9. SQL连接:where子句与on子句
  10. .NET中小数,浮点数和双精度之间的区别?