首页 > 其他分享 >13. 分组数据

13. 分组数据

时间:2024-10-29 23:31:06浏览次数:1  
标签:13 GROUP WHERE id 分组 子句 数据 HAVING

1. 数据分组

分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算

2. 创建分组

分组是在SELECT语句的GROUP BY子句中建立的。

比如:

select vend_id, count(*) as num_prods
from products
group by vend_id;

输出如下:

img

上面的SELECT语句指定了两个列,vend_id包含产品供应商的ID,num_prods为计算字段(用COUNT(*)函数建立)。GROUP BY子句指示MySQL按vend_id排序并分组数据。这导致对每个vend_id而不是整个表计算num_prods一次。

从输出中可以看到,供应商1001有3个产品,供应商1002有2个产品,供应商1003有7个产品,而供应商1005有2个产品。

因为使用了GROUP BY,就不必指定要计算和估值的每个组了。系统会自动完成。

GROUP BY子句指示MySQL分组数据,然后对每个组而不是整个结果集进行聚集。

在具体使用GROUP BY子句前,需要知道一些重要的规定:

  • GROUP BY子句可以包含任意数目的列。这使得能对分组进行嵌套(“GROUP BY 可以嵌套分组”是指在 GROUP BY 子句中可以指定多个列进行分组),为数据分组提供更细致的控制。

  • 如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。

    补充:

    “如果在 GROUP BY 子句中嵌套了分组,数据将在最后规定的分组上进行汇总”指的是在多层分组时,最终的聚合结果是基于最后一个分组条件进行汇总的。这意味着在所有指定的分组条件中,最后一个分组条件决定了最终的汇总结果。

    具体解释

    • 分组的顺序: 当你在 GROUP BY 中指定多个列时,数据库会首先按第一个列分组,然后在每个分组内再按第二个列分组,以此类推,直到最后一个列。最终的汇总是基于最后一个列。

    • 最终汇总的依据: 最后一个列的分组决定了如何计算聚合函数(如 SUM、COUNT 等)。这意味着在所有的分组中,最后一个分组的结果将是你查询返回的主要汇总信息。

  • GROUP BY子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。(不太理解,总感觉有点问题,不管这条了)

    不过这样写是错的:

    img

    这样写也是错的:

    img

  • 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出。

  • 如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。

  • GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。

补充:

使用ROLLUP:

使用WITH ROLLUP关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值。

比如:

select vend_id, count(*) as num_prods
from products
group by vend_id with rollup;

输出如下:

img

3. 过滤分组

除了能用GROUP BY分组数据外,MySQL还允许过滤分组,规定包括哪些分组,排除哪些分组。

例如,可能想要列出至少有两个订单的所有顾客。为得出这种数据,必须基于完整的分组而不是个别的行进行过滤。

我们已经看到了WHERE子句的作用(第6章中引入)。但是,在这个例子中WHERE不能完成任务,因为WHERE过滤指定的是行而不是分组。事实上,WHERE没有分组的概念。

MySQL为此目的提供了另外的子句,那就是HAVING子句。

HAVING非常类似于WHERE。事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。

补充:

  • HAVING支持所有WHERE操作符:

    在第6章和第7章中,我们学习了WHERE子句的条件(包括通配符条件和带多个操作符的子句)。所学过的有关WHERE的所有这些技术和选项都适用于HAVING。它们的句法是相同的,只是关键字有差别。

怎么过滤分组呢?请看:

select cust_id, count(*) as orders
from orders
group by cust_id
having count(*) >= 2;

输出如下:

img

最后一行增加了HAVING子句,它过滤COUNT(*) >=2(两个以上的订单)的那些分组。

注意:

  • HAVING和WHERE的差别

    这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在分组中。

那么,有没有在一条语句中同时使用WHERE和HAVING子句的需要呢?事实上,确实有。

假如想进一步过滤上面的语句,使它返回过去12个月内具有两个以上订单的顾客。为达到这一点,可增加一条WHERE子句,过滤出过去12个月内下过的订单。然后再增加HAVING子句过滤出具有两个以上订单的分组。

比如下面的例子,它列出具有2个(含)以上、价格为10(含)以上的产品的供应商:

select vend_id, count(*) as num_prods
from products
where prod_price >= 10
group by vend_id
having count(*) >= 2;

输出如下:

img

4. 分组和排序

GROUP BY 和 ORDER BY 是非常不同的。表13-1汇总了它们之间的差别。

img

(这个图也有点不理解,特别是第三条,不知道这个对不对)

表13-1中列出的第一项差别极为重要。我们经常发现用GROUP BY分组的数据确实是以分组顺序输出的。但情况并不总是这样,它并不是SQL规范所要求的。

此外,用户也可能会要求以不同于分组的顺序排序。仅因为你以某种方式分组数据(获得特定的分组聚集值),并不表示你需要以相同的方式排序输出。

应该提供明确的ORDER BY子句,即使其效果等同于GROUP BY子句也是如此。

解释下上面那段话是啥意思:

img

注意:

  • 不要忘记ORDER BY:

    一般在使用GROUP BY子句时,应该也给出ORDER BY子句。这是保证数据正确排序的唯一方法。千万不要仅依赖GROUP BY排序数据。

为说明GROUP BY和ORDER BY的使用方法,举个例子,它检索总计订单价格大于等于50的订单的订单号和总计订单价格:

select order_num, sum(quantity * item_price) as ordertotal
from orderitems
group by order_num
having sum(quantity * item_price) >= 50;

输出如下:

img

为按总计订单价格排序输出,需要添加ORDER BY子句,如下所示:

select order_num, sum(quantity * item_price) as ordertotal
from orderitems
group by order_num
having sum(quantity * item_price) >= 50
order by ordertotal;

img

在这个例子中,GROUP BY子句用来按订单号(order_num列)分组数据,以便SUM(*)函数能够返回总计订单价格。HAVING子句过滤数据,使得只返回总计订单价格大于等于50的订单。最后,用ORDER BY子句排序输出。

5. SELECT子句顺序

表13-2以在SELECT语句中使用时必须遵循的次序,列出迄今为止所学过的子句。

img
img

标签:13,GROUP,WHERE,id,分组,子句,数据,HAVING
From: https://www.cnblogs.com/hisun9/p/18514746

相关文章

  • 13.Java的IO流
    文件概念文件:保存数据的地方。文件流:文件在程序中是以流的形式来操作的。流:数据在数据源(文件)和程序(内存)之间经历的路径。输入流:数据从数据源(文件)到程序(内存)的路径。输出流:数据从程序(内存)到数据源(文件)的路径。常用操作构造方法方法说明File(Fileparent,......
  • GPU 学习笔记三:GPU多机多卡组网和拓扑结构分析(基于数据中心分析)
    文章目录一、概述二、数据中心(DC)2.1数据中心简介2.2传统数据中心的网络模型2.3脊叶网络模型(Spine-Leaf)2.4Facebook的Fabric网络架构三、基于数据中心的多机多卡拓扑3.1Spine-Leaf架构网络规模测算方法3.2NVIDIA多机多卡组网防止遗忘和后续翻找的麻烦,记录下平......
  • vue表单案例练习:vue表单创建一行数据及删除数据的实现与理解
    如何使用Vue:基本结构:1、引入Vue的核心JS文件2、准备Dom结构3、实例化组件通过el属性,挂载元素,绑定id为app的html元素通过data属性,定义数据,可以在html代码段中显示的数据4、获取数据数据绑定最常见的形式就是使用“Mustache”语法(双大括号)的文本插值@目录目标两个例......
  • 数据结构————map,set详解
    今天带来map和set的详解,保证大家分清楚一,概念map和set是一种专门用来搜索的容器或数据结构map能存储两个数据类型,我们称之为<key-value>模型set只能存储一个数据类型,我们称之为纯<key>模型它们的效率都非常非常高,我们来一个一个了解。二,详解map1,map的说明map是一个接......
  • P9131 [USACO23FEB] Problem Setting P 题解
    P9131[USACO23FEB]ProblemSettingP题解注意到最终形成的困难序列是一个不断包含的子集的关系,包含是非严格单调的,考虑转化为单调的形式易于计数dp。具体地,对于一些相同的困难值\(i\),算出其内部排列数\(g(i)\),于是转化成了单调的dp形式。于是实际上计算\(dp_{i}\)表示......
  • 20222413 2024-2025-1 《网络与系统攻防技术》实验三实验报告
    1.实验内容1.1学习总结本周的学习内容为恶意代码的概念、发展历史以及分析技术。我知晓了恶意代码的不同类型及其典型案例、攻击方式和危害。同时我了解了静态分析和动态分析所采用的技术方法。1.2实践内容(1)正确使用msf编码器,veil-evasion,自己利用shellcode编程等免杀工具或......
  • P9994 [Ynoi Easy Round 2024] TEST_132
    题意给定平面上\(n\)个点,保证两两横纵坐标不同:对于所有横坐标为\(x\)的点,权值\(v_i=v_i^2\)。询问所有纵坐标为\(y\)的点的权值之和。\(n\le10^6\)。Sol根号分治,考虑对于所有横坐标相同的点分组。对于修改操作,若当前修改的组大小\(\leB\),那么直接暴力修......
  • 数据库设计与范式及其应用
    数据库设计是数据库管理系统(DBMS)中的核心环节,良好的数据库设计不仅可以提高数据存取的效率,还能增强数据的可维护性和一致性。范式(Normalization)是一种设计原则,用于减少数据冗余和提高数据完整性。本文将深入探讨数据库设计中的范式及其实际应用。一、什么是范式范式是一系列......
  • DBeaver如何导出insert的sql数据
    前言我们在使用DBeaver连接数据库的时候,有时候需要将数据库某张表的数据全部导出,用于导入到其他的数据库。一般导出的格式有csv,也要sql语句,今天就来介绍下如何导出sql语句。这样在其他新的数据库中,就能直接执行插入了。如何操作首先,我们点击下我们要导出的数据库表,然后鼠标右击......
  • 数据模型和数据库之间的关系是什么
    文章开头段落:数据模型和数据库之间存在着密切的关系,具体表现在以下几个方面:定义结构、约束行为、规范操作、指导设计。其中,数据模型为数据库提供了结构化的框架,制定了数据存储的蓝图和方法,使得数据可以被高效地存储、检索和维护。定义结构是数据模型的核心任务之一,其影响力贯穿......