【postgresql 基础入门】分组查询 group by 子句的写法,分组条件过滤having子句的写法,多列的分组以及与join联合的多表分组

本文主要是介绍【postgresql 基础入门】分组查询 group by 子句的写法,分组条件过滤having子句的写法,多列的分组以及与join联合的多表分组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

分组查询与分组条件过滤

专栏内容

  • postgresql内核源码分析
  • 手写数据库toadb
  • 并发编程

个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

文章目录

  • 分组查询与分组条件过滤
  • 一、前言
  • 二、概述
  • 三、分组group by 介绍
    • 基本分组使用
    • 分组中使用聚合函数
    • 多表join中使用分组
    • 多列的分组
  • 四、分组条件having介绍
  • 五、总结
  • 六、结尾

一、前言


本文主要分享在postgresql 数据库中对查询结果进行分组group by,以及对分组进行条件过滤having,同时对它们的使用场景进行案例分享。

二、概述


在数据查询中,我们经常对数据进行分类,往往不止一种分类,分类的好处是将大的数据集能划分成更小的数据集,方便我们进行递归的分析,更精确的查找想要的数据。
那么如何进行分组,以及分组中的过滤查找呢?

  • 对结果集进行分组,是在前面介绍的基本查询 select ... from ... where ... 后面再使用 group by 关键字;

  • 在分组上进行按条件筛选过滤就不能使用where子句中的条件了,而是使用having关键字来指定条件;

下面我们来详细介绍。

三、分组group by 介绍


对查询结果数据进行按某个字段或某几个字段进行分组,使用关键字group by ,它的SQL语法如下:

SELECT column1, column2, ..., aggregate_function(column3)
FROM tablename1 group by column1,column2,...;

一般分组是配合聚合函数使用的,常用的聚合函数如sum求合、max/min求最大/小值、avg求平均值。

  • select 子句中要列出来要分组的列,同时可以增加聚合函数,计算分组中某个值;
  • 在group by子句中指定分组的列名,这样结果就会按指定列进行分组,并分别在每个分组中应用聚合函数计算;
  • 当然还可以增加where子句,对结果集进行过滤;而group by 子句是在where子句之后进行,也就是它应用于where过滤之后的结果集;

下面我们来看几个例子吧。

基本分组使用

在这里我们还是使用产品表与订单表,表的定义与数据准备如下:

-- 创建产品表  
CREATE TABLE products (  product_id INT PRIMARY KEY,  product_name VARCHAR(255) NOT NULL,  price DECIMAL(10, 2) NOT NULL,  category VARCHAR(255)  
);  -- 创建订单表  
CREATE TABLE orders (  order_id INT PRIMARY KEY,  product_id INT,  quantity INT NOT NULL,  region VARCHAR(255) NOT NULL,  order_date DATE NOT NULL,  FOREIGN KEY (product_id) REFERENCES Products(product_id)  
);

表中也准备了一些数据,查询如下:

postgres=# select * from products ;product_id | product_name |  price  | category
------------+--------------+---------+----------2 | shirt        |  202.40 | type23 | cake         |   37.80 | type45 | hat          |   88.40 | type26 | milk         |   19.80 | type41 | iphone       | 8999.01 | type57 | keyboard     |   92.01 | type54 | pencil       |    8.20 | type1
(7 rows)postgres=# select * from orders ;order_id | product_id | quantity | region  | order_date
----------+------------+----------+---------+------------1 |          1 |        8 | region1 | 2022-04-012 |          1 |      102 | region2 | 2022-06-013 |          2 |       19 | region1 | 2022-05-014 |          3 |        3 | region1 | 2022-04-015 |          4 |       58 | region2 | 2022-06-016 |          5 |        1 | region1 | 2022-05-017 |          6 |      106 | region1 | 2022-04-018 |          6 |       99 | region2 | 2022-06-019 |          4 |       32 | region1 | 2022-05-01
(9 rows)

下面我们执行一条最简单的分组查询

postgres=# select category  from products group by category;category
----------type1type2type5type4
(4 rows)

按产品类型进行分组,可以看到结果中列出了分组类型,等价于查询产品类型,并且使用distinct进行去重的结果。

分组中使用聚合函数

分组的常见用法,都是配合函合函数来进行统计分析。

postgres=# select min(quantity),max(quantity),avg(quantity), region as b from orders group by b;min | max |         avg         |    b
-----+-----+---------------------+---------1 | 106 | 28.1666666666666667 | region158 | 102 | 86.3333333333333333 | region2
(2 rows)

统计出各区域的订单中商品数量的最高水平、最低水平、还有平均水平,这里按区域进行分组,然后使用聚合函数进行统计;

在SQL中我们给区域字段region使用别名b,在group by中是可以引用别名。

多表join中使用分组

还可以在多表join时使用分组统计。

postgres=# select category, sum(price*quantity) from products p inner join orders o using(product_id) group by category;category |    sum
----------+-----------type1    |    738.00type2    |   3934.00type5    | 989891.10type4    |   4172.40
(4 rows)

统计商品大类的销售额,这里需要将products表与orders表进行内联接,才能将价格与销售数量结合起来。

多列的分组

当然也可以按几个列进行依次分组,在现实生活中也常常用到。

postgres=# select region, category, sum(price*quantity) amount from products p inner join orders o using(product_id) group by region,category order by region, amount;region  | category |  amount
---------+----------+-----------region1 | type1    |    262.40region1 | type4    |   2212.20region1 | type2    |   3934.00region1 | type5    |  71992.08region2 | type1    |    475.60region2 | type4    |   1960.20region2 | type5    | 917899.02
(7 rows)

按区域进行统计每种大类商品的销售额,这是在上个案例基础上再增加区域region列的分组,然后按区域进行排序,再按销售额升序排列。

四、分组条件having介绍


使用where子句对结果集进行条件过滤,那么对于按分组统计的结果可以使用条件进行过滤吗?

答案是肯定的,可以使用having子句对分组的统计结果进行条件过滤。

带有having子句的SQL语法格式如下:

SELECT column1, column2, ..., aggregate_function(column3)
FROM tablename1 group by column1,column2,... HAVING conditions;

group by 后面追加having关键字来指定条件;

这里不要搞混了,wherehaving的作用,虽然它们俩个都是带有条件的,where是对from子句中的原始表数据时行条件筛选,得到结果集,它是先于group by来执行;而having是对group by的分组结果进行条件过滤,是在group by之后执行。

下面我们来看一下如何使用。

postgres=# select min(quantity) as num, region from orders group by region having min(quantity) > 10;num | region
-----+---------58 | region2
(1 row)

对上面的分组聚合结果再过滤一下,只显示大于销售数量大于10的分组。

注意, having子句中不能使用select子句中的别名,也就是不能用num > 10这样的写法。

五、总结


本文分享了一个很有用的SQL语法,对结果集按类分组group by子句,它一般与聚合函数一起使用,分组之后对各个分组再进行统计分析,当然也可以对分组统计的结果再进行有条件的筛选,这就用到了having 子句,它是一个条件表达式,只是针对分组进行条件过滤。

同时在编写SQL时要注意,有了group by子句后,在select子句中要包括分组的列和对应的聚合函数。

六、结尾


非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

这篇关于【postgresql 基础入门】分组查询 group by 子句的写法,分组条件过滤having子句的写法,多列的分组以及与join联合的多表分组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/866791

相关文章

Python实现阶乘的四种写法

《Python实现阶乘的四种写法》本文主要介绍了Python实现阶乘的六种写法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录第一种:推导式+循环遍历列表内每个元素相乘第二种:调用functools模块reduce的php累计

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

MySQL中删除重复数据SQL的三种写法

《MySQL中删除重复数据SQL的三种写法》:本文主要介绍MySQL中删除重复数据SQL的三种写法,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录方法一:使用 left join + 子查询删除重复数据(推荐)方法二:创建临时表(需分多步执行,逻辑清晰,但会

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Oracle Expdp按条件导出指定表数据的方法实例

《OracleExpdp按条件导出指定表数据的方法实例》:本文主要介绍Oracle的expdp数据泵方式导出特定机构和时间范围的数据,并通过parfile文件进行条件限制和配置,文中通过代码介绍... 目录1.场景描述 2.方案分析3.实验验证 3.1 parfile文件3.2 expdp命令导出4.总结

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

Mybatis拦截器如何实现数据权限过滤

《Mybatis拦截器如何实现数据权限过滤》本文介绍了MyBatis拦截器的使用,通过实现Interceptor接口对SQL进行处理,实现数据权限过滤功能,通过在本地线程变量中存储数据权限相关信息,并... 目录背景基础知识MyBATis 拦截器介绍代码实战总结背景现在的项目负责人去年年底离职,导致前期规

Redis KEYS查询大批量数据替代方案

《RedisKEYS查询大批量数据替代方案》在使用Redis时,KEYS命令虽然简单直接,但其全表扫描的特性在处理大规模数据时会导致性能问题,甚至可能阻塞Redis服务,本文将介绍SCAN命令、有序... 目录前言KEYS命令问题背景替代方案1.使用 SCAN 命令2. 使用有序集合(Sorted Set)