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可以进行降序

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

目录
打赏
0
0
0
0
10
分享
相关文章
SQL查询太慢?实战讲解YashanDB SQL调优思路
本文是Meetup第十期“调优实战专场”的第二篇技术文章,上一篇《高效查询秘诀,解码YashanDB优化器分组查询优化手段》中,我们揭秘了YashanDB分组查询优化秘诀,本文将通过一个案例,助你快速上手YashanDB慢日志功能,精准定位“慢SQL”后进行优化。
【YashanDB知识库】字段加上索引后,SQL查询不到结果
【YashanDB知识库】字段加上索引后,SQL查询不到结果
OmniSQL:开源文本到SQL神器!自然语言秒转查询到复杂多表连接等SQL需求
OmniSQL是开源的文本到SQL转换模型,通过创新的数据合成框架生成250万条高质量样本,支持7B/14B/32B三种模型版本,能处理从简单查询到复杂多表连接等各种SQL需求。
168 16
OmniSQL:开源文本到SQL神器!自然语言秒转查询到复杂多表连接等SQL需求
玩转大数据:从零开始掌握SQL查询基础
玩转大数据:从零开始掌握SQL查询基础
139 35
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
如何在Django中正确使用参数化查询或ORM来避免SQL注入漏洞?
如何在Django中正确使用参数化查询或ORM来避免SQL注入漏洞?
258 77
利用 PolarDB PG 版向量化引擎,加速复杂 SQL 查询!完成任务领发财新年抱枕!
利用 PolarDB PG 版向量化引擎,加速复杂 SQL 查询!完成任务领发财新年抱枕!
122 14
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
83 1
SQL为什么不建议执行多表关联查询
本文探讨了SQL中不建议执行多表关联查询的原因,特别是MySQL与PG在多表关联上的区别。MySQL仅支持嵌套循环连接,而不支持排序-合并连接和散列连接,因此在多表(超过3张)关联查询时效率较低。文章还分析了多表关联查询与多次单表查询的效率对比,指出将关联操作放在Service层处理的优势,包括减少数据库计算资源消耗、提高缓存效率、降低锁竞争以及更易于分布式扩展等。最后,通过实例展示了如何分解关联查询以优化性能。
|
4月前
|
Java使用sql查询mongodb
通过MongoDB Atlas Data Lake或Apache Drill,可以在Java中使用SQL语法查询MongoDB数据。这两种方法都需要适当的配置和依赖库的支持。希望本文提供的示例和说明能够帮助开发者实现这一目标。
91 17

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等