【测试开发学习历程】MySQL分组查询与子查询 + MySQL表的联结操作

news2024/9/29 1:25:33

目录

1 MySQL分组查询与子查询

1.1 数据分组查询

1.2 过滤分组

1.3 分组结果排序

1.4 select语句中子句的执行顺序

1.5 子查询

2 MySQL表的联结操作

2.1 关系表

2.2 表联结

2.3 笛卡尔积

2.4 内部联结

2.5 外联结

2.6 自联结

2.7 组合查询


1 MySQL分组查询与子查询

1.1 数据分组查询

分组允许把数据表中的数据按照某个字段,分为多个组,字段值相同的为一组。分组是为了便于对每个组进行聚集计算;

分组是在select语句的group by子句中建立;

注意:group by只是创建分组,但并不保证分组里面的数据的排列顺序,需要使用order by子句对分组里面的数据进行排序。

使用group by语句对select查询的结果进行分组,以便统计:

select语句指定了两个列,vend_id为产品供应商的ID,prod_num为计算字段(使用count()函数);

group by子句按vend_id分组数据,这导致对每个vend_id而不是整个表计算prod_num一次,从而按照vend_id为单位,来计算每个组的总和;

注意:group by子句必须出现在where子句之后,order by子句在group by之后。where XXX group by YYY order by ZZZ

1.2 过滤分组

除了能用group by分组数据外,MySQL还允许对分组指定条件,规定包含哪些分组,排除哪些分组;

MySQL使用having子句来完成该操作;

where子句过滤指定的行,having子句过滤指定的分组。

如,过滤总数大于等于2的分组:

where与having同时使用,列出具有2个(含)以上,价格为10(含)以上的产品的供应商:

1.3 分组结果排序

  • select后面只能查看group by子句后有的列;
  • group by可以根据多个列进行分组,多个列分组即对多个列的组合值相同的进行分组;

1.4 select语句中子句的执行顺序

select语句中使用的子句必须按照一定的次序,下图列出来各个子句在select语句中出现的次序:

子句

说明

是否必须使用

SELECT

要返回的列或表达式

FROM

从中检索数据的表

仅在从表选择数据时使用

WHERE

行级过滤

GROUP BY

分组说明

仅在按组计算聚集时使用

HAVING

组级过滤

ORDER BY

输出排序顺序

LIMIT

要检索的行数

1.5 子查询

  • 前面我们讲的所有查询都是在单个数据库表中执行;
  • SQL还允许建立子查询,即嵌套在其他查询中的查询;
  • MySQL从4.1版本开始支持子查询,要使用子查询必须使用MySQL4.1或更高版本。

订单存储在两个表中:orders保存订单号,客户ID、订单日期;

各订单的物品信息保存在orderitems表中,order表不保存客户信息,它只保存客户的ID。实际的客户信息存储在customers表中;

如果需要列出订购物品编号TNT2的所有客户姓名,可以采用下列步骤:

  1. 查询包含物品TNT2的所有订单的编号;
  2. 查找前一步骤列出的订单编号的所有客户的ID;
  3. 查找前一步返回的所有客户ID的客户姓名;

上述每个步骤都可以单独作为一个查询来执行,可以把一条select语句返回的结果用于另一条select语句的where子句中。

方法一:用多个查询语句实现

(1)查找包含物品TNT2的所有订单的编号

(2)查找前一步骤列出的订单编号的所有客户的ID

(3)查找前一步列出的客户ID的客户姓名及其他信息

方法二:用子查询把多个查询语句组合起来 

使用子查询语句完成

在Where子句中使用子查询能够编写出功能很强并且很灵活的SQL语句。对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询。比子查询更优的查询方法是联结。

2 MySQL表的联结操作

2.1 关系表

为什么需要关系表?

假设有一个包含产品目录的数据库表,其中每种类别的产品占一行。对于每种物品要存储的信息包括产品描述和价格,以及生成该产品的供应商信息。

现在,假如有由同一供应商生产的多种物品,那么在何处存储供应商信息(如:供应商名、地址、联系方式等)呢?将这些数据与产品信息分开存储还是存储在同一张表里呢?通常的原则是分开存储,理由:

  • 因为同一供应商生产的每个产品的供应商信息都是相同的,对每个产品重复此信息既浪费时间又浪费存储空间
  • 如果供应商信息改变(如:供应商搬家或电话号码变动,只需要改动一次即可)
  • 如果有重复数据(即每种产品都存储供应商信息),很难保证每次输入该数据的方式都相同,不一致的数据在报表中很难利用。

在这个例子中,可建立两个表,一个存储供应商信息(vendors表),另一个存储产品信息(products表)。

关系数据可以有效地存储和方便地处理。因此,关系数据库的可伸缩性远比非关系数据库要好。

2.2 表联结

SQL最强大的功能之一就是能在数据检索查询的执行中联结表;

数据是存储在关系表中的,关系表的设计原则是保证把信息分解成多个表,一类数据一个表,各表通过某些常用的值互相关联。

2.3 笛卡尔积

笛卡尔积是由没有联结条件的表关系返回的结果,检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。

2.4 内部联结

创建链接:

where子句:

  • 在一条SELECT语句中联结几个表时,相应的关系是在运行中构造的。在数据库表的定义中并不存在能指示MySQL如何对表进行联结的东西。你必须自己做这件事情;
  • 在联结两个表时,你实际上做得是将第一个表中的每一行与第二个表中的每一行配对;
  • Where子句作为过滤条件,它只包含那些匹配给定条件(这里是联结条件)的行。没有Where子句,第一个表中的每个行将与第二个表中的每个行配对,而不管逻辑上是否可以配在一起。

上述语句中的select与前面的select语句相同,但from子句不同,这里两个表之间的关系是from子句的组成部分,以INNER JOIN指定。在使用这种语法时,联结条件用特定的ON子句而不是where子句。传递给ON的实际条件与传递给where的相同。

2.5 外联结

许多联结将一个表中的行与另一个表中的行相关联,但有时候需要包含没有关联行的那些行,例如,可能需要使用联结来完成以下工作:

  • 统计每个客户下了哪些订单,包括那些至今尚未下订单的客户;
  • 列出所有产品以及订购数量,包括没有人订购的产品;

在上述的例子中,联结包含了那些在相关表中没有关联行的行,这种类型的联结称为外部联结;

外部联结分为左外部联结和右外部联结;

左外部联结:以左边表为基准,按照过滤条件查找右边表的记录,如果匹配到,那么就组合成一行,并显示结果,如果没有匹配到,那么只显示左边表的字段,右边表中不存在的字段用空值NULL来表示。

右外部联结:作用和左联结刚好相反,以右边表为基准,去匹配左边的表,如果左边表字段为空,那么就用空值NULL来表示。 

左右外连接实例:

2.6 自联结

自联结为在同一个表中做联结操作;

例:假如发现某物品(其ID为DTNTR)存在问题,因此想知道生产该物品的供应商的其他产品是否也存在问题。此查询要求首先找到生产ID是DTNTR的物品的供应商,然后找出这个供应商生产的其他。

效率高于子查询

连结的注意事项:

  • 注意所使用的联结类型,一般我们使用内部联结,但使用外部联结也是有效的;
  • 保证使用正确的联结条件,否则将返回不正确的数据;
  • 应该总是指定联结条件,否则会得到笛卡尔积;
  • 在一个联结中可以包含多个表,甚至对每个联结可以采用不同的联结类型,虽然这样做是合法的,一般也很有用,但应该在一起测试它们前,分别测试每个联结,这样使故障排除更为简单。

2.7 组合查询

多数SQL查询都只包含从一个或多个表中返回数据的单条SELECT语句,MySQL也允许执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回;

这些组合查询通常称为并(union)或符合查询(compound query);

可用UNION操作符来组合数条SQL查询,利用UNION可以将多条select语句组合起来,将它们的结果组合成单个结果集。

上面的例子中,UNION从查询结果集中自动去除了重复的行,这是UNION的默认行为,但是如果需要,可以改变它;

如果要想返回所有匹配行,可使用UNION ALL来代替UNION关键字

在用UNION组合查询时,只能使用一条order by子句,它必须出现在最后一条SELECT语句之后;

对于结果集,不存在用一种方式排列一部分,而又用另一种方式排列另一部分的情况,因此不运行使用多条order by子句;

规则: 

  • UNION必须由两条或者以上的语句组成,语句之间用关键字UNION分隔(如果组合4条SELECT语句,将要使用3个UNION关键字);
  • UNION中的每个查询必须包含相同数量的列、表达式或聚集函数;
  • 列数据类型必须兼容。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1541325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LangChain-Chatchat知识库对话

前言 上次我们完成了Chatchat的本地部署,使用了LLM对话的功能。这次我们尝试一下其他的功能,之前总是有报错没有跑通,这次处理了几个问题之后才跑通了知识库对话和文件对话。 知识库对话 原理: 首先我们看这个图可以明白,知识库…

Redis学习二--常见问题及处理

基本概念 Redis基本概念数据结构 机制 持久化机制: RDB(内存快照):某一时刻的内存快照以二进制的方式写入磁盘,可以手动触发和自动触发。 优点:生成文件小,恢复速度快,适用于灾难恢复。 缺点&#xff1a…

03-SparkSQL入门

0 Shark Spark 的一个组件,用于大规模数据分析的 SQL 查询引擎。Shark 提供了一种基于 SQL 的交互式查询方式,可以让用户轻松地对大规模数据集进行查询和分析。Shark 基于 Hive 项目,使用 Hive 的元数据存储和查询语法,并基于Hiv…

MySQL5.6.11安装步骤(Windows7 64位)

MySQL5.6.11安装步骤(Windows7 64位) 1. 下载MySQL Community Server 5.6.21,注意选择系统类型(32位/64位) 2. 解压MySQL压缩包 将以下载的MySQL压缩包解压到自定义目录下。 3. 添加环境变量 变量名:MYS…

【项目设计】基于MVC的负载均衡式的在线OJ

项目代码(可直接下载运行) 一、项目的相关背景 学习编程的小伙伴,大家对力扣、牛客或其他在线编程的网站一定都不陌生,这些编程网站除了提供了在线编程,还有其他的一些功能。我们这个项目只是做出能够在线编程的功能。…

“低代码+平台”:驱动企业数字化转型与创新的新引擎

“低代码平台”作为一种新兴的软件开发范式,正逐渐成为企业快速响应市场变化、优化业务流程、提升数字化水平的重要手段。它的价值在于,将传统软件开发的复杂性大大降低,赋予了非技术人员或轻量级开发者快速构建应用的能力,并能灵…

可视化驯龙高手:Portainer——轻松驾驭Docker的图形化管理利器

在Docker容器技术的海洋中,Portainer如同一艘满载智能导航系统的旗舰,为我们提供了直观且易用的图形化管理界面,让繁杂的容器管理和运维工作变得轻松愉悦。本文将带你了解Portainer的基本功能,掌握其安装方法,并体验其…

摘录笔记——2024年3月22日

目录 一、背景 1.1 新人的选择困局 1.2 高人才密度环境下普通员工的成长效率困局 1.3 业务发展和个人成长的二元对立困局 1.4 中年打工人低费效比引发的职场生涯终结困局 二、人的本质 2.1 人的本质的定义 2.2 由“人的本质”引出的几个关键过程 2.2.1 认知指引实践&a…

【前端寻宝之路】学习和总结HTML表格的实现和合并

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-IWDj0gWiFt6IMq3x {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

啥是反射???

在Java编程中,反射(Reflection)是一种强大的工具,它允许程序在运行时检查类、接口、字段和方法的信息,并且可以动态地创建和操作对象。 一、反射的基本概念 反射是Java语言的一个特性,它允许程序在运行时对…

QML ShapePath绘制虚线

一.qml PathLine介绍 在 QML(Qt Modeling Language)中,PathLine 是 Path 元素的一个子类型,用于创建两点之间的直线段。Path 类型用于描述一个二维路径,可以用来绘制形状、曲线和直线。PathLine 是所有路径曲线中最简单…

从0写一个问卷调查APP的第13天-1

1.今日任务 我也只是一个大学生,有什么思路不对的地方给我指出来哟! 分析:上次我们实现了任务调查的插入。但是我们插入的问卷调查只有它的标题,也就是这个问卷调查是什么我们告诉数据库了,但是现在我们还没有给它添加任何问题&…

域控操作十三:域用户登陆前显示标题以及文本

域控用户在登录前会先显示这个,才能输入密码登录

【数字图像处理matlab系列】使用数组索引进行简单的图像裁剪、二次取样操作

【数字图像处理matlab系列】使用数组索引进行简单的图像裁剪、二次取样操作 【先赞后看养成习惯】求点赞+关注+收藏! pout.tif是一张matlab自带的图片,图像尺寸是291*240,使用imread读取该图像>> a = imread(pout.tif); >> imshow(a);对图像a进行上下翻转操作,…

深入理解 Docker 镜像

1. Docker 镜像的底层原理 1.1 分层的镜像 以我们的pull 命令为例,在下载的过程中我们可以看到docker的镜像好像是一层一层的在下载。 1.2 UnionFS(联合文件系统) 联合文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次…

vector类详解及重要函数实现

🪐🪐🪐欢迎来到程序员餐厅💫💫💫 今日主菜:vector类 主厨:邪王真眼 所属专栏:c专栏 主厨的主页:Chef‘s blog 坚持下去,成功不是目的&a…

C#学习笔记1:C#基本文件结构与语法

现在开始我的C#学习之路吧,这也许不适合0编程基础的人看,因为我会C语言了,笔记做的可能有思维上的跳跃,如果0基础可能会觉得有些地方转折得莫名奇妙,但我的学习笔记实操还是比较多的,基本都是真实运行程序结…

QTabWidget的tabbar不同方向显示 文字方向设置 图标跟随变化 实现方式 qt控件绘制原理

先来看结果图:(参考博客:QTabWidget中tab页文本水平或垂直设置_pyqt tab_widget.settabposition(qtabwidget.west) 字体-CSDN博客) 从图中可知,"普通"是qt自己的样式,但是很明显,在垂…

Ubuntu18.04桌面版设置静态IP地址

引用: Ubuntu配置静态IP_ubuntu配置静态ip地址-CSDN博客 正文 默认Unbuntu 18.04 Desktop桌面版使用 netplan 管理网卡网络地址。使用Unbuntu 18.04 桌面版配置,可以通过桌面上的设置图标配置网卡的静态IP地址。 点击桌面右上角下拉框,点击“设置”按…

蓝桥杯(2):python基础算法【上】

时间复杂度、枚举、模拟、递归、进制转换、前缀和、差分、离散化 1 时间复杂度 重要是看循环,一共运行了几次 1.1 简单代码看循环 #时间复杂度1 n int(input()) for i in range(1,n1):for j in range(0,i):pass ###时间复杂度:123....nn(1n)/2 所以…