【重学 MySQL】四十一、子查询举例与分类

【重学 MySQL】四十一、子查询举例与分类

  • 引入子查询
    • 在SELECT子句中引入子查询
    • 在FROM子句中引入子查询
    • 在WHERE子句中引入子查询
    • 注意事项
  • 子查询分类
    • 标量子查询
    • 列子查询
    • 行子查询
    • 表子查询
  • 子查询注意事项
    • 子查询的位置
    • 子查询的返回类型
    • 别名的使用
    • 性能考虑
    • 相关性
    • 错误处理
    • 逻辑清晰
  • 总结

在这里插入图片描述

在MySQL中,子查询是一种嵌套在其他查询中的查询,它可以出现在SELECT、FROM、WHERE等子句中,为外部查询提供数据或条件。

引入子查询

在MySQL中,引入子查询通常是为了解决一些复杂的查询需求,这些需求可能无法直接通过简单的SELECT、FROM、WHERE等语句组合来实现。子查询允许你在一个查询内部嵌套另一个查询,从而可以基于内部查询的结果来过滤或计算外部查询的数据。

子查询可以在SQL语句的多个部分中引入,但最常见的位置是SELECT子句、FROM子句和WHERE子句。

在SELECT子句中引入子查询

子查询可以用在SELECT子句中作为列的一部分,返回单个值或多个值(但通常作为单个值使用,并可能需要聚合函数)。

SELECT employee_id, name, (SELECT AVG(salary) FROM employees) AS avg_salary
FROM employees;

这个例子中,子查询计算了所有员工的平均工资,并将其作为avg_salary列返回给每个员工。

在FROM子句中引入子查询

子查询也可以作为FROM子句的一部分,将子查询的结果视为一个临时表(或内联视图),然后可以在外部查询中对其进行进一步的操作。

SELECT *
FROM (SELECT employee_id, MAX(salary) AS max_salaryFROM employeesGROUP BY department_id
) AS max_salaries
WHERE max_salary > 50000;

这个例子中,子查询首先按部门分组并找出每个部门的最高工资,然后外部查询从这个临时表中选择工资高于50000的记录。

在WHERE子句中引入子查询

子查询在WHERE子句中非常常见,用于提供过滤条件。

SELECT *
FROM employees
WHERE salary > (SELECT AVG(salary)FROM employeesWHERE department_id = 1
);

这个例子中,子查询计算了部门ID为1的员工的平均工资,然后外部查询选择了工资高于这个平均值的所有员工。

注意事项

  • 性能:子查询可能会影响查询的性能,特别是当子查询返回大量数据时。在可能的情况下,考虑使用JOIN操作或其他优化技术。
  • 可读性:复杂的子查询可能会降低SQL语句的可读性。在编写复杂的查询时,考虑使用CTE(公共表表达式)或临时表来分解查询逻辑。
  • 逻辑清晰:确保子查询的逻辑清晰、明确,并且与外部查询的逻辑一致。
  • 错误处理:注意处理子查询中可能出现的错误,如除零错误、空值(NULL)处理等。

通过合理引入子查询,你可以解决许多复杂的查询问题,但也要注意避免过度使用,以免降低查询性能或增加维护难度。

子查询分类

子查询按照返回结果集的不同,可以分为四种类型:标量子查询、列子查询、行子查询和表子查询。

标量子查询

定义:标量子查询返回的结果集是一个标量值,即一行一列。

举例:查询工资高于公司平均工资的员工信息。

SELECT * FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

在这个例子中,子查询(SELECT AVG(salary) FROM employees)计算了公司所有员工的平均工资,并作为一个标量值返回给外部查询,用于比较员工的工资是否高于这个平均值。

列子查询

定义:列子查询返回的结果集是一列多行。

举例:查询没有参与过某个项目的员工信息。

假设有两个表:employees(员工表)和projects(项目参与表),其中projects表记录了员工参与的项目ID。

SELECT * FROM employees
WHERE employee_id NOT IN (SELECT DISTINCT employee_id FROM projects WHERE project_id = 'P001');

在这个例子中,子查询(SELECT DISTINCT employee_id FROM projects WHERE project_id = 'P001')返回了参与项目’P001’的所有员工ID,外部查询则选择那些没有在这个列表中的员工。

行子查询

定义:行子查询返回的结果集是一行多列,通常与比较操作符(如=、<>、IN等)结合使用,但MySQL中直接使用行子查询的情况较少,更多是通过JOIN或其他方式实现类似功能。

说明:虽然MySQL支持行子查询的概念,但在实际使用中,可能更倾向于使用JOIN操作来实现相同的功能,因为JOIN在性能上通常更优,且语法更清晰。

表子查询

定义:表子查询返回的结果集是多行多列,可以看作是一个临时的表,在外部查询中作为FROM子句的一部分。

举例:查询库存量少于订单所需量的产品。

假设有两个表:products(产品表)和orders(订单表)。

SELECT * FROM (SELECT product_id, SUM(quantity) AS required_quantityFROM ordersGROUP BY product_id
) AS order_details
JOIN products ON order_details.product_id = products.product_id
WHERE products.stock_quantity < order_details.required_quantity;

在这个例子中,子查询首先计算了每个产品的订单总需求量,然后将这个结果作为一个临时表order_details与外部的产品表products进行JOIN操作,以找出库存量少于订单所需量的产品。

子查询注意事项

在使用MySQL的子查询时,需要注意以下几个方面以确保查询的正确性和效率:

子查询的位置

  • 子查询可以嵌套在SQL语句中的多个位置,包括SELECT子句、FROM子句、WHERE子句、GROUP BY子句、HAVING子句等。了解子查询可以放置的位置有助于编写更灵活的查询语句。

子查询的返回类型

  • 标量子查询:返回单个值(单行单列),常用于比较操作。
  • 列子查询:返回一列多行,常用于IN、ANY、ALL等操作符中。
  • 行子查询:返回一行多列,但在MySQL中直接使用行子查询的情况较少,通常通过JOIN或其他方式实现。
  • 表子查询:返回多行多列,可以看作是一个临时的表,在外部查询中作为FROM子句的一部分。

别名的使用

  • 当在FROM子句中使用子查询时,必须为子查询结果集指定别名,以便在外部查询中引用。
  • 在SELECT子句中使用子查询时,如果子查询返回单行单列,通常不需要指定列别名,但为了提高可读性,建议总是指定别名。

性能考虑

  • 子查询可能会降低查询效率,特别是当子查询返回大量数据时。在可能的情况下,考虑使用JOIN操作代替子查询,因为JOIN操作通常更高效。
  • 对于复杂的子查询,特别是多层嵌套的子查询,要注意优化查询逻辑,减少不必要的计算和数据检索。

相关性

  • 相关子查询:子查询的结果依赖于外部查询的结果。这种子查询在每次外部查询处理一行时都会重新执行。
  • 不相关子查询:子查询的结果不依赖于外部查询的结果。这种子查询在整个外部查询执行前只执行一次。

在编写相关子查询时要特别注意性能问题,因为它们可能会显著增加查询的复杂度和执行时间。

错误处理

  • 确保子查询的语法正确,并且返回的数据类型与外部查询中的数据类型兼容。
  • 注意处理可能出现的空值(NULL)情况,因为子查询可能返回空值,这会影响外部查询的结果。

逻辑清晰

  • 编写子查询时,要确保逻辑清晰、易于理解。复杂的子查询可能会让其他开发者难以理解和维护。
  • 在可能的情况下,将复杂的子查询分解为更简单的部分,并使用临时表或CTE(公共表表达式)来存储中间结果。

综上所述,使用MySQL子查询时需要注意位置、返回类型、别名使用、性能考虑、相关性、错误处理和逻辑清晰性等方面。通过遵循这些注意事项,可以编写出既高效又易于维护的查询语句。

总结

子查询是MySQL中非常强大的功能,它允许在查询中嵌套其他查询,从而实现复杂的查询逻辑。通过合理使用不同类型的子查询,可以高效地解决各种数据库查询问题。

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

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

相关文章

一文带你读懂分库分表,分片,Sharding的许多概念

一文带你读懂分库分表,分片,Sharding的许多概念 分库是将一个库拆分为多个库&#xff0c;分表就是将一个表拆分为多个表。分库分表有垂直拆分和水平拆分。垂直拆分一般是按照业务将表分到不同的库中&#xff08;此种不在本发的讨论范围&#xff09;。水平拆分是将表的数据拆分…

Java---异常及处理

一.异常 1.概念 程序的非正常执行。高级语言都有异常处理机制&#xff08;C&#xff0c;Java&#xff09; 2.一般处理异常的方法 Scanner sc new Scanner(System.in);System.out.println("请输入一个数字:");String s sc.nextLine();if (s.matches("[0-9]&qu…

ViTamin——视觉-语言时代的可扩展视觉模型设计

人工智能咨询培训老师叶梓 转载标明出处 尽管视觉-语言模型&#xff08;VLMs&#xff09;已经取得了显著的成就&#xff0c;但在图像编码器的选择上&#xff0c;传统的视觉Transformer&#xff08;ViT&#xff09;依然是主流。尽管Transformer在文本编码领域已经证明了其有效性…

【C++笔记】初始模版和STL简介

【C笔记】初始模版和STL简介 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】初始模版和STL简介前言一.初始模版1.1泛型编程1.2函数模版1.3类模板 二.STL简介2.1什么是STL2.2STL的版本2.3STL的六大组件2.4STL的重要…

TypeScript概念讲解

简单来说&#xff0c;TypeScript 是 JavaScript 的一个超集&#xff0c;支持 ECMAScript 6 标准&#xff1b; TypeScript 由微软开发的自由和开源的编程语言&#xff1b; TypeScript 设计目标是开发大型应用&#xff0c;它可以编译成纯 JavaScript&#xff0c;编译出来的 Jav…

这款免费工具让你的电脑焕然一新,专业人士都在用

HiBit Uninstaller 采用单一可执行文件的形式,无需复杂的安装过程,用户可以即刻开始使用。这种便捷性使其成为临时使用或紧急情况下的理想选择。尽管体积小巧,但其功能却异常强大,几乎不会对系统性能造成任何负面影响。 这款工具的一大亮点是其多样化的功能。它不仅能够常规卸…

QT:常用类与组件

1.设计QQ的界面 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> #include <QLineEdit> #include <QLabel>//自定义类Widget,采用public方式继承QWidget&#xff0c;该类封装了图形化界面的相关操作&#xff…

第十三周:机器学习

目录 摘要 Abstract 一、生成式对抗网络&#xff08;上&#xff09; 1、引入——generator 2、discriminator 3、GAN算法 4、GAN的理论 5、GAN的训练技巧 二、word2vec——gensim实践 1、引入 2、 word2vec模型 3、fasttext模型 总结 摘要 本周学习了对GAN进行了…

栏目一:使用echarts绘制简单图形

栏目一&#xff1a;使用echarts绘制简单图形 前言1. 在线编辑图形1.1 折线图1.2 柱状图1.3 扇形图 2. 本地绘制图表2.1 下载echarts.min.js2.2 创建一个简单的图形 前言 Echarts是一款基于JavaScript的可视化图表库。它提供了丰富的图表类型和交互功能&#xff0c;可以用于在网…

qt6 使用QPSQL

qt6 自带pg数据库驱动&#xff1a; pro文件加个说明&#xff1a; 引用位置添加&#xff08;按需添加&#xff0c;这里我就大致加一下&#xff09;&#xff1a; test code: 理想情况当然是要用pool,这里只是演示调用而已 QSqlError DbTool::testConnection(const QString &…

JSON的C实现(上)

JSON的C实现&#xff08;上&#xff09; JSON的C实现&#xff08;上&#xff09;前言JSON简介JSON的C实现思路小结 JSON的C实现&#xff08;上&#xff09; 前言 JSON是众多项目中较为常见的数据交换格式&#xff0c;为不同项目、系统间的信息交换提供了一个规范化标准。JSON…

测试用例的进阶二

1. 按开发阶段划分 1.1 测试金字塔 从上到下&#xff0c;对于测试人员代码就是要求越来越低&#xff1b; 从下到上&#xff0c;越来越靠近用户&#xff1b; 从下到上&#xff0c;定位问题的成本越来越高&#xff1b; 1.2 单元测试(Unit Testing) 单元测试是对软件组成单元进…

《迁移学习》—— 将 ResNet18 模型迁移到食物分类项目中

文章目录 一、迁移学习的简单介绍1.迁移学习是什么&#xff1f;2.迁移学习的步骤 二、数据集介绍三、代码实现1. 步骤2.所用到方法介绍的文章链接3. 完整代码 一、迁移学习的简单介绍 1.迁移学习是什么&#xff1f; 迁移学习是指利用已经训练好的模型&#xff0c;在新的任务上…

Linux防火墙-常用命令,零基础入门到精通,收藏这一篇就够了

我们经过上小章节讲了Linux的部分进阶命令&#xff0c;我们接下来一章节来讲讲Linux防火墙。由于目前以云服务器为主&#xff0c;而云服务器基本上就不会使用系统自带的防火墙&#xff0c;而是使用安全组来代替了防火墙的功能&#xff0c;可以简单理解安全组就是web版的防火墙&…

Windows环境下训练开源图像超分项目 ECBSR 教程

ECBSR 介绍 ECBSR&#xff08;Edge-oriented Convolution Block for Real-time Super Resolution&#xff09;是一种针对移动设备设计的轻量级超分辨率网络。它的核心是一种可重参数化的构建模块&#xff0c;称为边缘导向卷积块&#xff08;ECB&#xff09;&#xff0c;这种模…

Qt 首次配置 Qt Creator 14.01 for Python

前言&#xff1a; 如何用QT实现Python的配置的交互界面。本文从0开始&#xff0c;进行实践的介绍。 在上一节里面&#xff0c;我们做了社区版本的配置&#xff1a; https://blog.csdn.net/yellow_hill/article/details/142597007?spm1001.2014.3001.5501 这一节&#xff0…

vue+UEditor附件上传问题

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…

快速实现AI搜索!Fivetran 支持 Milvus 作为数据迁移目标

Fivetran 现已支持 Milvus 向量数据库作为数据迁移的目标&#xff0c;能够有效简化 RAG 应用和 AI 搜索中数据源接入的流程。 数据是 AI 应用的支柱&#xff0c;无缝连接数据是充分释放数据潜力的关键。非结构化数据对于企业搜索和检索增强生成&#xff08;RAG&#xff09;聊天…

Java SPI 原理、样例

在 Java 中&#xff0c;SPI&#xff08;Service Provider Interface&#xff09;全称为服务提供者接口&#xff0c;它是一种用于实现框架扩展和插件化的机制。 一、SPI 作用 允许在运行时动态地为接口查找服务实现&#xff0c;而不需要在代码中显式地指定具体的实现类。 这使得…

利用多模态输入的自我中心运动跟踪与理解框架:EgoLM

随着增强现实(AR)和虚拟现实(VR)技术的发展,对自我中心(第一人称视角)运动的精确跟踪和理解变得越来越重要。传统的单一模态方法在处理复杂场景时存在诸多局限性。为了解决这些问题,研究者们提出了一种基于多模态输入的自我中心运动跟踪与理解框架——EgoLM。本文将详细…