SQL-分组查询

简介: SQL-分组查询

DQL-分组查询

语法

注意:括号中的语句是可选的!

SELECT 字段列表  FROM 表名 [ WHERE  条件 ] GROUP BY 分组字段名 [ HAVING 分组后过滤条件 ];

在做题之前,大家可以发现这条语句中,有两个地方是指定条件的,一个是where之后的条件,一个是having之后的条件,那么肯定有疑问,where和having之间到底有什么区别?

where与having区别

1.执行时机不同:where是分组之前进行过滤,不满足where条件,则不参与分组;而having是分组之后对结果进行过滤。

2.判断条件不同:where不能对聚合函数进行判断,而having中可以。


案例:

1.根据性别分组 , 统计男性员工 和 女性员工的数量

首先,我们先写下基础查询的语法

select * from emp group by gender ;

1.因为我们根据性别分组,所以后面跟的分组的字段名是gender

2.分组我们知道,我们通常配合着聚合函数来操作,因为having中是可以使用聚合函数进行判断的

3.本题需要统计男性员工和女性员工的数量,此时要统计数量,那么我们要用的聚合函数是count还是sum?这里要统计的是数量,所以我们选用count,因此我们需要讲聚合函数加入进去,这里回顾一下聚合函数的语法

select 聚合函数(字段列表) from 表名 ;

4.于是在这里需要写入count(*),对分组的男性员工与女性员工进行统计

select count(*) from emp group by gender ;

此时结果如下:

此时不是很明了,因为我们并不知道到底男性是7还是女性是7?因此我们可以在查询的时候把gender也查询出来,查询多个字段的语法我们回顾一下:

select 字段1,字段2,字段3 ..... from  表名 ;

于是我们在count(*)之前再加入gender字段,需要将gender查询出来,代码如下:

select gender, count(*) from emp group by gender ;

执行结果如下:

注意!如果gender写在count(*)的后面则查询的结果gender字段就在count(*)后面,执行如下图:



2.根据性别分组 , 统计男性员工 和 女性员工的平均年龄

参照上一案例的思路的话,直接将统计数量的count函数改为平均值avg函数再在括号里将age字段给入即可

select gender, avg(age) from emp group by gender ;

执行结果如下:

3.查询年龄小于35的员工 , 并根据工作地址分组 , 获取员工数量大于等于3的工作地址

我们是思路是可以一步一步来完善这些条件,那么第一步先查询出年龄小于35岁的员工

select * from emp where age<35 ;

然后根据工作地址进行分组,那么就是加入group by

select * from emp where age<35 group by workaddress ;

再然后获取员工数量大于等于3的工作地址,要求取员工的数量,所以*此时应该变为一个count(*),注意,肯定有人会疑惑怎么能用count(*)?大家要明白分组时会执行聚合,也就是说age<35的员工分成不同工作地址后执行了聚合,不同的工作地址看成不同的一整个表,所以用*是没有问题的,总结来说就是select gender, count(*) from emp group by gender ;  select gender首先他会筛选性别这个字段 ,然后通过 group by 进行分组,这个时候他会自动去统计字段里面的类别,分为男和女2个组,然后,再通过,count(*)去统计每个组的人数。此时就能够根据工作地址workaddress分组,然后获取每一个工作地址的员工年龄小于35的员工数量

select count(*) from emp where age<35 group by workaddress ;

执行结果如下:

当然此时我们很难看出是哪个工作地址的员工的数量所以我们再补全一下代码,将workaddress也进行一个查询,当然workaddress要放置于count(*)前面,注意workaddress和count(*)之间的逗号不能省略

select workaddress , count(*) from emp where age<35 group by workaddress ;

执行结果如下:


此时可以看出年龄小于35的员工,在上海的有1人,在北京的有6人,而其他工作地址的数据为什么没有被查询出来,因为它们不满足一个条件就是,它们的年龄没有小于35,所以没有被查询出来

接下来就要考虑查询员工数量大于等于3的工作地址,意思就是要在分组的基础上再进行过滤,我们知道where是分组之前进行过滤,而having是分组之后对结果进行过滤,所以我们肯定要用到having,而且where是不能判断聚合函数的,所以你不能写where count(*) >= 3,我们只能让where去判断age<35,让having去判断count(*) >= 3

select workaddress, count(*)  from emp where age < 35 group by workaddress having count(*) >= 3 ;

执行结果如下:

当然,这里给大家介绍一下我们也可以这样写,给它起一个别名,address_count,起了别名之后,后面这一块就不用count(*)了,用别名来进行分组之后的过滤是一样的

select workaddress, count(*) address_count from emp where age < 45 group by workaddress having address_count >= 3;

4.统计各个工作地址上班的男性及女性员工的数量

可以按照前面的方式一步步来完善操作,就不赘述这么多了

1.统计各个地址,男性及女性员工的数量,那么肯定是要根据两个方面进行分组的,一个是地址,一个是性别。当然我们需要特别注意的是多个分组字段之间也是要用逗号分隔的,千万不能漏掉

select * from emp group by gender , workaddress ;

2.统计员工数量肯定是需要用到count(*)

select count(*) from emp group by gender , workaddress ;

执行如下:


3.做到第2部其实条件已经基本完善了,但是不太直观,如果想要查询的数据更好看的话就再添加一下查询字段和别名

select workaddress, gender, count(*) '数量' from emp group by gender , workaddress ;

执行如下:


分组查询注意事项:

执行顺序: where > 聚合函数 > having 。(where在分组之前进行过滤,而分组的时候会执行聚合函数,而having是在分组聚合之后过滤的)

支持多字段分组, 具体语法为 : group by columnA,columnB    (注意两个字段中间的逗号不能漏掉)

分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。

这句话如何理解?如图

大家看,此时我是男9女7,如果我前面加一个name能不能执行?可以,但是执行出来的name值没有任何意义,女性显示一个沈立聪什么含义呢?女性只有沈立聪嘛,女性有很多,它只是展示出来第一个女性的姓名,所以没有任何意义



DQL- 排序查询

排序在日常开发中是非常常见的一个操作,有升序排序,也有降序排序。


语法

SELECT 字段列表  FROM  表名 ORDER BY 字段1  排序方式1 , 字段2  排序方式2 ;
大家由此代码可以看出,实际上排序操作是支持多字段排序的,而排序时,第一个就是指定字段名,第二个指定排序方式

排序方式

1.ASC : 升序(默认值)

2.DESC: 降 序

注意事项:

1.如果是升序, 可以不指定排序方式ASC ;

2.如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序 ;

案例:

1.根据年龄对公司的员工进行升序排序

select * from emp order by age asc;
select * from emp order by age;

执行如图 :


如果要进行降序排序则对asc进行一个替换,替换为desc即可


写法上的一些思考

1.基础语法先写出来

select * from emp ;

2.再写排序关键字order by

select * from emp order by age asc;


2.根据入职时间对员工进行降序排序

select * from emp order by entrydate desc;

执行结果如图:

此时可观察到降序

3.根据年龄对公司的员工进行升序排序 , 年龄相同 , 再按照入职时间进行降序排序

select * from emp order by age asc , entrydate desc ;
注意,这里多字段排序的意思是,如果前一个字段信息相同了,排序不了之后,才会根据第二个字段进行排序,不是说字段1可以进行升序,字段2可以进行降序

多字段排序,多字段之间使用逗号分隔

相关文章
|
18天前
|
SQL 存储 人工智能
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
Vanna 是一个开源的 Python RAG(Retrieval-Augmented Generation)框架,能够基于大型语言模型(LLMs)为数据库生成精确的 SQL 查询。Vanna 支持多种 LLMs、向量数据库和 SQL 数据库,提供高准确性查询,同时确保数据库内容安全私密,不外泄。
84 7
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
|
25天前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
35 8
|
1月前
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
54 4
|
1月前
|
SQL 监控 关系型数据库
SQL语句当前及历史信息查询-performance schema的使用
本文介绍了如何使用MySQL的Performance Schema来获取SQL语句的当前和历史执行信息。Performance Schema默认在MySQL 8.0中启用,可以通过查询相关表来获取详细的SQL执行信息,包括当前执行的SQL、历史执行记录和统计汇总信息,从而快速定位和解决性能瓶颈。
|
1月前
|
SQL 存储 缓存
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
122 10
|
1月前
|
SQL 关系型数据库 MySQL
|
2月前
|
SQL 数据库 开发者
功能发布-自定义SQL查询
本期主要为大家介绍ClkLog九月上线的新功能-自定义SQL查询。
|
2月前
|
SQL 移动开发 Oracle
SQL语句实现查询连续六天数据的方法与技巧
在数据库查询中,有时需要筛选出符合特定时间连续性条件的数据记录
|
2月前
|
SQL Java 数据库连接
如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
【10月更文挑战第6天】在代码与逻辑交织的世界中,我从一名数据库新手出发,通过不断探索与实践,最终成为熟练掌握JDBC的开发者。这段旅程充满挑战与惊喜,从建立数据库连接到执行SQL语句,再到理解事务管理和批处理等高级功能,每一步都让我对JDBC有了更深的认识。示例代码展示了如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
118 5
|
2月前
|
SQL 数据挖掘 数据库
SQL查询每秒的数据:技巧、方法与性能优化
id="">SQL查询功能详解 SQL(Structured Query Language,结构化查询语言)是一种专门用于与数据库进行沟通和操作的语言
下一篇
DataWorks