MySQL基础进阶:编写复杂查询

编写复杂查询

  • 1. 子查询
  • 2. IN运算符
  • 3. 子查询VS连接
  • 4. ALL关键字
  • 5. ANY关键字
  • 6. 相关子查询
  • 7. EXISTS运算符
  • 8. SELECT子句中得子查询
  • 9. FROM子句中得子查询

1. 子查询

子查询: 任何一个充当另一个SQL语句的一部分的 SELECT 查询语句都是子查询,子查询是一个很有用的技巧。子查询的层级用括号实现。

MySQL执行时会先执行括号内的子查询(内查询),将获得的结果返回给外查询,子查询不仅可用在 WHERE …… 中,也可用在 SELECT …… 或 FROM …… 等子句中

SELECT*
FROM products
WHERE unit_price > (SELECT unit_priceFROM productsWHERE name LIKE '%Lettuce%'
)SELECT*
FROM employees
WHERE salary > (SELECT AVG(salary) AS average_salaryFROM employees
)

2. IN运算符

当需要判定的条件中有多个数值时,用到IN和NOT IN运算符。(可以是字符也可以是数字)

SELECT *
FROM products
WHERE product_id NOT IN(SELECT DISTINCT product_id  -- distinct关键字用于属性名前,得到不重复值FROM order_items
)

3. 子查询VS连接

子查询(Subquery)是将一张表的查询结果作为另一张表的查询依据并层层嵌套,其实也可以先将这些表连接(Join)合并成一个包含所需全部信息的详情表再直接在详情表里筛选查询。两种方法一般是可互换的,具体用哪一种取决于性能(Performance)和可读性(readability)。

SELECT *
FROM products
LEFT JOIN order_items USING (product_id)
WHERE order_id IS NULL  
-- 等同于在WHERE中采用子查询SELECTDISTINCT customer_id,first_name,last_name
FROM customers
LEFT JOIN orders USING (customer_id)
LEFT JOIN order_items USING (order_id)
WHERE product_id = 3    
-- 对于多表之间的查询,先连接成大表,然后再查询可读性更强SELECT customer_id,first_name,last_name
FROM customers
WHERE customer_id IN (SELECT o.customer_idFROM order_items oiJOIN orders o USING (order_id)WHERE product_id = 3
)  -- 采用子查询和外连接共同作用来进行多表查询

4. ALL关键字

(MAX (……)) 和 > ALL(……) 等效可互换:“比这里面最大的还大” = “比这里面的所有的都大”
从以下代码来进行对比:

SELECT *
FROM invoices
WHERE invoice_total > (SELECT MAX(invoice_total) -- 用于表中的属性值计算最大值FROM invoicesWHERE client_id = 3
)SELECT *
FROM invoices
WHERE invoice_total > ALL ( -- 用于子查询后结构的计算最大值SELECT invoice_totalFROM invoicesWHERE client_id = 3
)

5. ANY关键字

同SOME,表示其中任何一个
= ANY (……) 与 IN (……) 等效;
< ANY/SOME (……) 与 < (MIN (……)) 等效

SELECT *
FROM clients
WHERE client_id = ANY (    -- 可采用IN或= SOME来替换SELECT client_idFROM invoicesGROUP BY client_idHAVING COUNT(*) > 2
)

6. 相关子查询

  • 非相关子查询:子查询先查出整体的某平均值或满足某些条件的一列id,作为主查询的筛选依据,这种子查询与主查询无关,会先一次性得出查询结果再返回给主查询供其使用。
  • 关子查询:子查询是依赖主查询的,子查询的判定中需要引入主查询的属性值(需要为主查询中表名命别名),每一条记录的主查询对应的子查询结果也会发生改变。这种关联查询是在主查询的每一行/每一条记录层面上依次进行的,另外也正因为这一点,相关子查询会比非关联查询执行起来慢一些。

Note:伪代码其实就是注释的表达方式,一种按照程序执行步骤编写的注释,中英文都可以

SELECT *
FROM employees e
WHERE salary > (  -- 相当于执行循环计算,子查询用到了主查询中的属性值SELECT AVG(salary)FROM employeesWHERE office_id = e.office_id
)

7. EXISTS运算符

  • IN + 子查询 等效于 EXIST + 相关子查询,如果前者子查询的结果集过大占用内存,用后者逐条验证更有效率。
  • EXIST()本质上是根据是否为空返回TRUE和FALSE,而IN 是获取返回的数值
  • EXIST也可以加NOT取反
SELECT * 
FROM clients
WHERE client_id IN (  -- 判断的是某些数值SELECT DISTINCT client_idFROM invoices
)SELECT DISTINCT client_id,name
-- 外连接可能产生大量重复项,需要剔除
FROM clients
JOIN invoices USING (client_id)SELECT * 
FROM clients c   -- 数据库本质上就是对表格数据的逐条判断筛选,然后联系到大量关系型数据库表格
WHERE EXISTS (
-- 类似判断语句,符合条件返回ture,则将此条记录输出
-- 对于clients表格中记录进行输出,不会产生重复SELECT *FROM invoicesWHERE client_id = c.client_id
)

NOTE:

  1. EXISTS(…) 函数相当于是前置的 … IS NULL(共同点:都是根据是否为空返回布林值)
  2. WHERE 确实是逐条验证筛选行/记录的
  3. EXISTS也是相关子查询
  4. 对于大电商来说,如果用IN+子查询法,子查询可能会返回一个百万量级的产品列表,这种情况还是用EXIST+相关子查询逐条验证法更有效率

8. SELECT子句中得子查询

不仅WHERE筛选条件里可以用子查询,SELECT选择子句和FROM来源表子句也能用子查询。

SELECT选择语句是用来确定查询结果选择包含哪些字段,每个字段都可以是一个表达式,而每个字段表达式里的元素除了可以是原始的列,具体的数值,也同样可以是其它各种花里胡哨的子查询的结果。

SELECT invoice_id,invoice_total,(SELECT AVG(invoice_total) FROM invoices) AS invoice_average,-- '123' AS Test 命名属性值,同时给其赋值。-- 当需要记录值逐条输出时,不能直接用聚合函数。必须和GROUP BY语句联合输出/*用括号+子查询改变顺序,【子查询 (SELECT AVG(invoice_total) FROM invoices)是作为一个数值结果 152.388235 加入主查询语句的】*/invoice_total - (SELECT invoice_average) AS difference/*SELECT表达式里要用原列名,不能直接用别名invoice_average要用列别名的话用子查询(SELECT 同级的列别名)即可*/
FROM invoices
Note:可以理解为给属性列来赋值
SELECT client_id,name,(SELECT SUM(invoice_total) FROM invoices WHERE client_id = c.client_id) AS total_sales,-- 子查询相对主查询clients,会进行5次循环查询。若用GRUOP BY则只会产生4组数值(SELECT AVG(invoice_total) FROM invoices) AS average,(SELECT total_sales - average) AS difference
FROM clients c

Note:形成表格过程中一定注意行中列数要匹配。

9. FROM子句中得子查询

子查询的结果同样可以充当一个“虚拟表”作为FROM语句中的来源表,即将筛选查询结果作为来源再进行进一步的筛选查询。但注意只有在子查询不太复杂时进行这样的嵌套,否则最好用后面讲的视图先把子查询结果储存起来再使用。

复杂的子查询再嵌套进FROM里会让整个查询看起来过于复杂,最好是将子查询结果储存为视图,然后再直接使用该视图作为来源表。(形成新表,然后查询。)

FROM子句中的子查询一般不用。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XML简介XML 使用教程XML的基本结构XML的使用场景

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…

汽车IVI中控开发入门及进阶(三十三):i.MX linux开发之开发板

前言: 大部分物料/芯片,不管MCU 还是SoC,都会有原厂提供配套开发板,有这样一个使用原型,在遇到问题时或者进行开发时可以使用。 i.MX 8QuadXPlus MEK board: 1、要测试display显示器,可使用i.MX mini SAS将“LVDS1_CH0”端口连接到LVDS到HDMI适配器的cable。 2、要测试…

微服务部署上线过程总结

目录 一、找到适合自己的部署方式 二、开始部署&#xff0c;先安装需要的环境 2.1 梳理一下都需要安装什么软件 2.2 配置数据库环境 2.3 配置redis 2.4 配置nacos 2.5 配置rabbitmq 2.6 配置docker环境 三、环境配置好了&#xff0c;开始部署后端 3.1 梳理后端都…

仓库管理系统12--供应商设置

1、添加供应商窗体 2、布局控件UI <UserControl x:Class"West.StoreMgr.View.SupplierView"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc"http://…

使用python做飞机大战

代码地址: 点击跳转

【论文阅读】伸缩密度比估计:Telescoping Density-Ratio Estimation

文章目录 一、文章概览&#xff08;一&#xff09;问题提出&#xff08;二&#xff09;文章工作 二、判别比估计和密度鸿沟问题三、伸缩密度比估计&#xff08;一&#xff09;核心思想&#xff08;二&#xff09;路标创建&#xff08;三&#xff09;桥梁构建&#xff08;四&…

Linux 生产消费者模型

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux初窥门径⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多Linux知识   &#x1f51d; 前言 1. 生产消费者模型 1.1 什么是生产消…

每日一题——Python实现PAT乙级1005 继续(3n+1)猜想(举一反三+思想解读+逐步优化)五千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码逻辑概述 时间复杂度分析 空间复杂度分析 总结 我要更强 代码优化点…

Nginx详解-安装配置等

目录 一、引言 1.1 代理问题 1.2 负载均衡问题 1.3 资源优化 1.4 Nginx处理 二、Nginx概述 三、Nginx的安装 3.1 安装Nginx 3.2 Nginx的配置文件 四、Nginx的反向代理【重点】 4.1 正向代理和反向代理介绍 4.2 基于Nginx实现反向代理 4.3 关于Nginx的location路径…

Jetson系列机载电脑创建热点模式配置方法

Jetson nano为例—— 创建热点模式配置方法 1.1、新建一个 WiFi 在屏幕右上角找到网络图标&#xff0c;点击后选择“Edit Connections”选项&#xff0c;进入选择网络连接页面&#xff0c;然后点击左下角加号&#xff0c;新建一个连接&#xff0c;类型选择 WiFi 后点击 “cre…

如何选择适合自己的巴比达内网穿透方案

选择适合自己的巴比达内网穿透方案&#xff0c;需要考虑几个关键因素&#xff0c;包括您的具体需求、安全性要求、技术水平以及预算。以下是一些选择巴比达内网穿透方案的建议步骤&#xff1a; 1. 确定需求和用途 首先&#xff0c;需要明确您希望通过内网穿透实现的具体目标和…

【linux学习---1】点亮一个LED---驱动一个GPIO

文章目录 1、原理图找对应引脚2、IO复用3、IO配置4、GPIO配置5、GPIO时钟使能6、总结 1、原理图找对应引脚 从上图 可以看出&#xff0c; 蜂鸣器 接到了 BEEP 上&#xff0c; BEEP 就是 GPIO5_IO05 2、IO复用 查找IMX6UL参考手册 和 STM32一样&#xff0c;如果某个 IO 要作为…

DP:解决路径问题

文章目录 二维DP模型如何解决路径问题有关路径问题的几个问题1.不同路径2.不同路径Ⅱ3.下降路径最小和4.珠宝的最高价值5.地下城游戏 总结 二维DP模型 二维动态规划&#xff08;DP&#xff09;模型是一种通过引入两个维度的状态和转移方程来解决复杂问题的技术。它在许多优化和…

使用VMware创建Ubuntu 24.04【一】

系列文章目录 第二章 使用Ubuntu安装Frappe-Bench【二】 文章目录 系列文章目录前言相关链接下载地址虚拟机创建与运行初始化系统中配置 前言 VMware是一个虚拟化软件&#xff0c;它允许用户在一台计算机上模拟多个虚拟计算机环境。通过使用VMware&#xff0c;用户可以轻松地…

【Python】已解决:AttributeError: ‘function’ object has no attribute ‘ELement’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;AttributeError: ‘function’ object has no attribute ‘ELement’ 一、分析问题背景 在Python编程中&#xff0c;AttributeError通常表明你试图访问一个对象…

【Linux】生物信息学常用基本命令

wget网址用于直接从网上下载某个文件到服务器&#xff0c;当然也可以直接从网上先把东西下到本地然后用filezilla这个软件来传输到服务器上。 当遇到不会的命令时候&#xff0c;可以使用man “不会的命令”来查看这个命令的详细信息。比如我想要看看ls这个命令的详细用法&…

K8S 集群节点扩容

环境说明&#xff1a; 主机名IP地址CPU/内存角色K8S版本Docker版本k8s231192.168.99.2312C4Gmaster1.23.1720.10.24k8s232192.168.99.2322C4Gwoker1.23.1720.10.24k8s233&#xff08;需上线&#xff09;192.168.99.2332C4Gwoker1.23.1720.10.24 当现有集群中的节点资源不够用&…

FFmpeg教程-三-播放pcm文件-1

目录 一&#xff0c;下载SDL 二&#xff0c;在Qt中测试 1&#xff0c;在pro文件中加入路径 2&#xff0c;在.cpp文件中加入头文件 3&#xff0c;进行测试 4&#xff0c;显示结果 一&#xff0c;下载SDL 通过编程的方式播放音视频&#xff0c;也是需要用到这2个库: FFmpeg…

2本Top,4本纯正刊,25天即录!7月刊源表已更新!

本周投稿推荐 SCI • 能源技术类&#xff0c;1.5-2.0&#xff08;来稿即录25天&#xff09; • 计算机类&#xff0c;2.0-3.0&#xff08;纯正刊29天录用&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; CNKI • 7天录用-检索&#xff08;急录友好&a…

Python处理异常用操作介绍

Python中的异常处理主要用于捕获和处理程序运行过程中出现的错误。 在编写Python程序时&#xff0c;我们经常会遇到各种错误&#xff0c;如语法错误、运行时错误等。为了确保程序的稳定性和健壮性&#xff0c;我们需要对可能出现的错误进行捕获和处理。本文将介绍Python中常用的…