持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
前言
我们在日常工作中会经常进行数据查询 有一些数据比较复杂 就需要我们非常认真的去编写SQL 在最近的工作中 我发现自己对于一下SQL中的知识淡忘了 使用起来没有那么得心应手 就重新复习一下
正文
分组 Group By
这个用的非常多 可能不是很常用的人慢慢就忘记一些写法 首先就整理游戏啊Group By 的用法
1、group by 的解释我们都是知道的
可以通过数据中的某一个 或者多个字段进行分组 一般我们会在统计上面去使用
2、group by 的用法
- select 字段 from 表 where 条件 group by 字段1,字段2,字段3
- select 字段 from 表 group by 字段1,字段2,字段)having 过滤条件
注意:where 是先过滤,再分组;having 是分组后再过滤 多个字段通过逗号分割
4、需要注意的地方
Group By中Select指定的字段限制
-
select后的字段:
- 要么就要包含在Group By语句的后面,作为分组的依据;
- 要么就要被包含在聚合函数中。
-
错误:
- SELECT name, salary FROM student GROUP BY name
- select 后的字段 salary 不在 group by 后面,所以salary无法显示全部值。
-
正确1:
- SELECT name, salary FROM student GROUP BY name , salary
- select 后的字段 name,salary 都包含在group by 后面,两个字段分组 name,salary。
-
正确 2:
- SELECT name,MAX(salary) FROM student GROUP BY name
- select 后的字段 salary 虽然不在 group by 后面,但是在聚合函数MAX(salary)里面,所以只会有一个值会正确。
这一点可能会有些人好奇 我在数据库执行SELECT name, salary FROM student GROUP BY name
没有任何问题啊 那说明你的sql_model是宽松模式 MySQL5.6和MySQL5.7默认的sql_mode模式参数是不一样的。
5.6的mode是NO_ENGIN_SUBSTITUTION,表示一个空值,相当于没有模式设置,可以理解为宽松模式。5.7的mode是STRICT_TRANS_TABLES,也就是严格模式 在严格模式 就是出现异常 还是要注意
查看模式:
select @@GLOBAL.sql_mode
复制代码
如果想要测试这个效果的同学可以通过下面这个语句改成严格模式
SET @@sql_mode = sys.list_add(@@sql_mode, 'ONLY_FULL_GROUP_BY');
复制代码
再次运行不规范的SQL 出现异常
更改回宽松模式
SET @@sql_mode = sys.list_drop(@@sql_mode, 'ONLY_FULL_GROUP_BY');
复制代码
可能有些人感觉我有毛病啊改成严格模式 但是 我们在实际开发中可能不知道数据库是什么模式还是需要注意这一点的
having 过滤
注意几点
1、having必须和group by一起用,且在group by后面
2、having 基本都是和聚合函数使用的
3、就是你要知道什么是group by 不要和order by 搞混了
4、where过滤行,having过滤组
having的用法
大白话就是先通过sql语句把所有数据查询出来,再用 group by 进行分组,然后把分完组的数据用聚合函数进行统计,只不过查询语句和聚合函数之间需要用having连接;(group by 、having、聚合函数通常一起使用)
结构
SELECT *|字段列表 [as 别名] FROM 表名 [WHERE 子句] [GROUP BY 子句][HAVING 子句][ORDER BY 子句][LIMIT 子句]
复制代码
SQL
select pid FROM node group by pid having pid > 0
复制代码
聚合函数使用
select pid FROM node group by pid having SUM(pid) > 2
复制代码
执行顺序:where(数据查询) -> group by(数据编组) -> having(结果过滤) -> order by(排序)
其实之前一直有一个疑问 为什么一定要和group by 一直使用 自己的理解是 having相当于是为了分组删选而生的 如果having能够单独使用那么where就是一个比较尴尬的角色了 为了避免既生瑜何生亮的问题就只能各司其职
练习
联系
1、创建表
create table student(num int ,name varchar(24),age int)
insert into student values(1,'A',21);
insert into student values(2,'B',21);
insert into student values(3,'A',21);
insert into student values(4,'A',21);
insert into student values(5,'A',21);
insert into student values(6,'C',21);
insert into student values(7,'B',21);
复制代码
问题一 :查询有重复的姓名
思路 首先是分组 我们平常查重可能都会使用count
所以也要使用 我们需要找到 count > 1 的数据
实现:
select name from student GROUP BY name HAVING count(name) > 1
复制代码
问题二:查询重复姓名学生的所有信息
解题思路:select * from student可以查看所有学生的信息,怎么查看重复的呢?上面我们已经知道了有哪些是重复的名字,那么我们只需要判断,哪些名字在重复的名字里面即可
select * from student where name in (select name from student GROUP BY name HAVING count(name) > 1)
复制代码
时间有点晚了 明天再找一些例子练习 诸君顺利