Oracle 第19章:高级查询技术
在Oracle数据库中,高级查询技术是数据库管理员和开发人员必须掌握的重要技能。这些技术能够帮助优化查询性能,简化复杂的查询逻辑,并提高数据处理的效率。本章将重点讨论两个关键概念:子查询和连接与并集操作。
子查询
定义:
子查询(Subquery)是指嵌套在另一个SQL语句中的查询。子查询可以出现在SELECT、INSERT、UPDATE或DELETE语句中,也可以作为其他子查询的一部分。根据其返回的结果数量,子查询可以分为单行子查询和多行子查询。
单行子查询:
单行子查询只返回一行结果。它们通常用于比较操作,例如使用=, <>, >, <等比较运算符。
示例:
假设我们有一个员工表employees和一个部门表departments。我们要找出工资高于平均工资的所有员工的名字。
SELECT first_name, last_name
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
在这个例子中,(SELECT AVG(salary) FROM employees)是一个单行子查询,它计算所有员工的平均工资。
多行子查询:
多行子查询可以返回多行结果。它们经常与IN, ANY和ALL关键字一起使用。
示例:
如果我们想找到所有属于销售部门的员工,而销售部门的ID为100,我们可以这样做:
SELECT first_name, last_name
FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE department_name = 'Sales');
这里,IN关键字用来检查employees表中的department_id是否存在于由子查询返回的列表中。
连接与并集操作
连接(Joins):
连接是用于从多个表中组合数据的一种方法。根据连接条件的不同,可以有多种类型的连接,包括内连接(INNER JOIN)、外连接(LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN)和自连接(Self Join)等。
内连接:
内连接返回两个表中满足连接条件的记录。
示例:
要获取每个员工的名字及其所在部门的名称,可以执行以下查询:
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id;
外连接:
外连接不仅返回满足连接条件的记录,还返回一个或两个表中不符合条件的记录。对于这些记录,结果集中来自不匹配表的列将包含NULL值。
左外连接:
左外连接返回左表中的所有记录,即使右表中没有匹配项。
示例:
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id;
这将列出所有员工,即使有些员工不属于任何已知的部门。
并集操作(Unions):
并集操作用于合并两个或更多SELECT语句的结果集。UNION操作符会自动去除重复的行,而UNION ALL则保留所有行,包括重复的行。
示例:
如果想要查找所有在’IT’或’Sales’部门工作的员工,可以使用如下查询:
SELECT first_name, last_name
FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE department_name = 'IT')
UNION
SELECT first_name, last_name
FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE department_name = 'Sales');
子查询的其他用法
相关子查询(Correlated Subqueries)
相关子查询是指子查询依赖于外部查询中的某个值。这意味着子查询会针对外部查询的每一行执行一次。
示例:
假设我们有一个订单表orders和一个订单详情表order_details。我们想要找出每个订单的总金额。
SELECT o.order_id, (SELECT SUM(od.quantity * od.price)FROM order_details odWHERE od.order_id = o.order_id) AS total_amount
FROM orders o;
在这个例子中,子查询计算了每个订单的总金额,它依赖于外部查询中的o.order_id。
EXISTS 和 NOT EXISTS
EXISTS 和 NOT EXISTS 用于检测子查询是否返回任何行。如果子查询返回至少一行,则 EXISTS 返回 TRUE;否则返回 FALSE。NOT EXISTS 则相反。
示例:
假设我们有一个客户表customers和一个订单表orders。我们想要找出所有从未下过订单的客户。
SELECT c.customer_id, c.customer_name
FROM customers c
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id);
不同类型的连接
自连接(Self Join)
自连接是指在一个表上进行的连接操作,其中表自身被当作两个不同的表来处理。这种连接通常用于处理具有层次结构的数据。
示例:
假设我们有一个员工表employees,其中包含员工的直接上级信息。我们想要找出每个员工的上级姓名。
SELECT e1.first_name AS employee, e1.last_name, e2.first_name AS manager, e2.last_name
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.employee_id;
交叉连接(CROSS JOIN)
交叉连接返回两个表的笛卡尔积,即第一个表的每一行与第二个表的每一行组合。
示例:
假设我们有两个表colors和sizes,我们想要生成所有颜色和尺寸的组合。
SELECT c.color, s.size
FROM colors c
CROSS JOIN sizes s;
并集操作的高级用法
UNION ALL 与性能
UNION ALL 不会去除重复的行,因此通常比 UNION 更快。如果不需要去重,建议使用 UNION ALL。
示例:
假设我们有两个表sales_q1和sales_q2,我们想要合并两个季度的销售数据。
SELECT * FROM sales_q1
UNION ALL
SELECT * FROM sales_q2;
使用并集操作处理复杂查询
并集操作可以用于处理复杂的查询需求,例如将多个来源的数据合并成一个结果集。
示例:
假设我们有一个产品表products和一个促销表promotions,我们想要列出所有产品及其促销价格(如果有促销)。
SELECT p.product_id, p.product_name, p.price AS regular_price, NULL AS promo_price
FROM products p
UNION ALL
SELECT p.product_id, p.product_name, NULL AS regular_price, pr.promo_price
FROM products p
JOIN promotions pr ON p.product_id = pr.product_id;
性能优化技巧
- 索引优化:确保在连接条件和子查询中使用的列上有适当的索引。
- 避免不必要的子查询:尽量减少子查询的使用,特别是在可以使用连接的情况下。
- 使用合适的连接类型:选择最合适的连接类型,以减少不必要的数据扫描。
- 分页查询:对于大数据量的查询,使用分页查询可以提高性能。
- 查询重构:有时重新编写查询可以显著提高性能,特别是当涉及到复杂的子查询和连接时。
通过这些高级查询技术,你可以更高效地管理和查询数据,解决复杂的业务需求。希望这些示例和解释对你有所帮助!
接下来我们将继续深入探讨一些更高级的主题,包括子查询的优化、复杂连接的应用、以及并集操作的高级技巧。此外,我们还会介绍一些实用的性能优化策略和最佳实践。
子查询的优化
避免相关子查询
相关子查询可能会导致性能问题,因为它需要为外部查询的每一行执行一次子查询。可以通过使用连接或其他方法来优化。
示例:
假设我们有一个订单表orders和一个订单详情表order_details。我们想要找出每个订单的总金额。
原始查询:
SELECT o.order_id, (SELECT SUM(od.quantity * od.price)FROM order_details odWHERE od.order_id = o.order_id) AS total_amount
FROM orders o;
优化后的查询:
SELECT o.order_id, SUM(od.quantity * od.price) AS total_amount
FROM orders o
JOIN order_details od ON o.order_id = od.order_id
GROUP BY o.order_id;
使用 WITH 子句(Common Table Expressions, CTE)
CTE 可以提高查询的可读性和性能,尤其是在处理复杂的子查询时。
示例:
假设我们有一个员工表employees和一个部门表departments。我们想要找出每个部门的最高工资和对应的员工。
原始查询:
SELECT d.department_name, e.first_name, e.last_name, e.salary
FROM departments d
JOIN employees e ON d.department_id = e.department_id
WHERE (d.department_id, e.salary) IN (SELECT department_id, MAX(salary)FROM employeesGROUP BY department_id
);
优化后的查询:
WITH max_salaries AS (SELECT department_id, MAX(salary) AS max_salaryFROM employeesGROUP BY department_id
)
SELECT d.department_name, e.first_name, e.last_name, e.salary
FROM departments d
JOIN employees e ON d.department_id = e.department_id
JOIN max_salaries ms ON e.department_id = ms.department_id AND e.salary = ms.max_salary;
复杂连接的应用
多表连接
在实际应用中,经常需要连接多个表来获取所需的数据。多表连接可以通过逐步连接的方式来实现。
示例:
假设我们有一个订单表orders、一个订单详情表order_details和一个产品表products。我们想要列出每个订单的详细信息,包括产品名称和数量。
SELECT o.order_id, p.product_name, od.quantity
FROM orders o
JOIN order_details od ON o.order_id = od.order_id
JOIN products p ON od.product_id = p.product_id;
外连接的高级用法
外连接可以用于处理不完整或缺失的数据。通过使用不同的外连接类型,可以灵活地处理各种情况。
示例:
假设我们有一个客户表customers、一个订单表orders和一个支付表payments。我们想要列出所有客户的订单和支付情况,即使某些客户没有订单或支付记录。
SELECT c.customer_id, c.customer_name, o.order_id, p.payment_id, p.amount
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
LEFT JOIN payments p ON o.order_id = p.order_id;
并集操作的高级技巧
使用 UNION ALL 优化性能
如前所述,UNION ALL 不会去除重复的行,因此通常比 UNION 更快。在不需要去重的情况下,应优先使用 UNION ALL。
示例:
假设我们有两个表sales_q1和sales_q2,我们想要合并两个季度的销售数据。
SELECT * FROM sales_q1
UNION ALL
SELECT * FROM sales_q2;
处理复杂的数据合并
并集操作可以用于处理复杂的查询需求,例如将多个来源的数据合并成一个结果集。
示例:
假设我们有一个产品表products、一个促销表promotions和一个折扣表discounts,我们想要列出所有产品的促销价格和折扣价格。
SELECT p.product_id, p.product_name, p.price AS regular_price, NULL AS promo_price, NULL AS discount_price
FROM products p
UNION ALL
SELECT p.product_id, p.product_name, NULL AS regular_price, pr.promo_price, NULL AS discount_price
FROM products p
JOIN promotions pr ON p.product_id = pr.product_id
UNION ALL
SELECT p.product_id, p.product_name, NULL AS regular_price, NULL AS promo_price, d.discount_price
FROM products p
JOIN discounts d ON p.product_id = d.product_id;
性能优化策略和最佳实践
-
索引优化:
- 确保在连接条件和子查询中使用的列上有适当的索引。
- 考虑使用复合索引(Composite Indexes)来提高性能。
-
避免全表扫描:
- 尽量使用索引和过滤条件来减少扫描的数据量。
- 使用
EXPLAIN PLAN来分析查询的执行计划,找出潜在的性能瓶颈。
-
合理使用临时表:
- 对于复杂的查询,可以考虑将中间结果存储在临时表中,以减少重复计算。
- 临时表可以在多次查询中复用,提高整体性能。
-
分页查询:
- 对于大数据量的查询,使用分页查询可以显著提高性能。
- 使用
ROWNUM或OFFSET和FETCH子句来实现分页。
-
查询重构:
- 有时重新编写查询可以显著提高性能,特别是当涉及到复杂的子查询和连接时。
- 考虑使用视图(Views)来封装复杂的查询逻辑,提高代码的可维护性。
-
使用绑定变量:
- 在动态生成的SQL语句中使用绑定变量,可以减少SQL解析的时间,提高性能。
- 绑定变量还可以防止SQL注入攻击,提高安全性。
-
定期维护数据库:
- 定期分析和优化表的统计信息,确保查询优化器能够生成最优的执行计划。
- 定期清理不再需要的数据,减少表的大小,提高查询性能。
通过这些高级查询技术和性能优化策略,你可以更高效地管理和查询数据,解决复杂的业务需求。希望这些内容对你有所帮助!如果你有任何具体的问题或需要进一步的解释,请随时告诉我。
相关文章:
Oracle 第19章:高级查询技术
在Oracle数据库中,高级查询技术是数据库管理员和开发人员必须掌握的重要技能。这些技术能够帮助优化查询性能,简化复杂的查询逻辑,并提高数据处理的效率。本章将重点讨论两个关键概念:子查询和连接与并集操作。 子查询 定义: 子…...
Excel:vba运行时错误“7“:内存溢出错误
我这里出现这个错误是在批注中插入图片时报错 原因:我插入的图片不都是jpg的类型的,但是其中的两张图片是webp类型的,但是我把文件后缀名修改成了jpg,以为变成了jpg类型的图片,但是图片在批注里面无法显示,所以运行到第…...
【MyBatis源码】BoundSql分析
基础 BoundSql是对SQL语句及参数信息的封装,它是SqlSource解析后的结果。Executor组件并不是直接通过StaticSqlSource对象完成数据库操作的,而是与BoundSql交互。BoundSql是对Executor组件执行SQL信息的封装,具体实现代码如下: …...
KTHREAD--InitialStack和KernelStack和TSS的esp0
InitialStack和TSS.esp0的关系,在这里可以看到 mov ecx, [esi_KTHREAD.InitialStack] ; esi: newthread lea eax, [ecx-210h] ; 越过FPXSAVE指令存储地址 test byte ptr [eax-1Ah], 2 ; 判断efalgs寄存器的VIF位是否为1 jnz short loc_458743 sub eax, 10h…...
Skia基础运用(Ubuntu环境下使用BUILD.gn)
1.拉取代码 git clone https://skia.googlesource.com/skia python tools/git-sync-deps // 这一步可能会出现部分错误,再次执行直到成功 // 这里面拉取完三方库之后会拉取node,linux等压缩包,从google下载上面执行完,代码就完全…...
Vue中props和data的优先级哪个更高?
前言 Vue组件之间的数据传递是一个非常重要的环节。而在组件内部,我们经常会用到props和data来管理和传递数据。那么,问题来了:当props和data有冲突时,哪个优先级更高呢? 为了更好地理解这个问题,我们先来…...
springboot2.x使用SSE方式代理或者转发其他流式接口
文章目录 1.需求描述2.代码2.1.示例controller2.2.示例service2.3.示例impl 3.测试 1.需求描述 使用SSE的方式主要还是要跟前端建立一个EventSource的链接,有了这个连接,然后往通道里写入数据流,前端自然会拿到流式数据,写啥拿啥…...
consul入门教程
一、介绍Consul Consul是由HashiCorp开发的一种服务发现和配置管理工具,它可以提供分布式系统所需的多个关键功能,如服务发现、配置管理、键值存储等。Consul可以帮助开发人员轻松构建分布式系统,提高系统的可靠性和可扩展性。 二、Consul实…...
软考:大数据架构设计
大数据总结 大数据处理系统的特征 1、鲁棒性和容错性 2、低延迟读取和更新能力 3、横向扩容 4、通用性 5、延展性 6、即席查询能力 7、最少维护能力 8、可调试性 Lambda架构 批处理层 存储数据集和生成Batch View 管理主数据集,原始的,不可变的&…...
token无感刷新+处理并发的后端方案
问题描述: 当用户通过登陆后进入一个web网站,会把token保存到localStorage。假设token过期时间30min。 那么当用户在网站快乐地玩耍了30min后,这时进行了一次提交表单,它会被重定向到登陆页面。 作为用户:我表单填了…...
【系统设计】让 Java “动起来”:动态语言与静态语言的比较及 DSL 实现
在编程语言的世界里,语言的特性决定了它们在不同场景下的适用性。动态语言和静态语言是两种常见的编程范式,它们的差异不仅影响开发者的使用习惯,还决定了它们在某些应用场景中的表现。在这篇博文中,我们将通过Python和Java这两种…...
TCP Analysis Flags 之 TCP Keep-Alive
前言 默认情况下,Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态,并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时,会对每个 TCP 数据包进行一次分析,数据包按照它们在数据包列表中出现的顺序进行处理。可…...
mfc140u.dll丢失怎么办? mfc140u.dll文件缺失的修复技巧
mfc140u.dll 是 Microsoft Foundation Classes (MFC) 库的一部分,它是 Visual Studio 2015 的组件之一,主要服务于使用 C 编写的 Windows 应用程序。这个动态链接库文件包含了 MFC 14.0 Unicode 版本的实现代码,为应用程序提供运行时支持。当…...
Spring Security使用
文章目录 Spring Security的起点FilterChain重写重写登录验证逻辑增加CSRF Token增加方法权限校验 Spring Security的起点 在AbstractApplicationContext.refresh()方法时,子类ServletWebServerApplicationContext会创建一个ServletContextInitializerBeans这个Bea…...
CSS网页布局综合练习(涵盖大多CSS知识点)
该综合练习就是为这个学校静态网页设置CSS样式,使其变成下面的模样 其基本骨架代码为: <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content…...
解决 Hardhat Verify 超时
问题背景 今天在学习使用Hardhat进行verify 合约 到 Ethscan的时候,出现了如下报错 fafafafadeMacBook-Air Web3_Solidity_Study % npx hardhat verify --network sepolia XXXXXXXXXXXXXXXXXXXXXXXX "10" Successfully verifie…...
ACIS创建各种基本体,举例说明
ACIS(Advanced CAD Interoperability System)是一个广泛使用的三维几何建模内核,它支持创建和操作各种基本的三维几何体。虽然ACIS没有专门的函数来直接创建某些特定的基本体(如椭球体),但可以通过一系列变…...
[CISCN 2019华北]PWN1-好久不见7
Partial RELRO 表示部分 RELRO 保护已启用。在这种情况下,只有某些部分(如 GOT 中的只读部分)是只读的。 NX enabled 表示这个二进制文件启用了 NX 保护,数据段是不可执行的。这可以防止某些类型的代码注入攻击。 这里是ida识别…...
代码随想录day16| 513找树左下角的值 、 路径总和 、 从中序与后序遍历序列构造二叉树
代码随想录day16| 找树左下角的值 、 路径总和 、 从中序与后序遍历序列构造二叉树 513找树左下角的值层序遍历法递归法 路径总和112. 路径总和113. 路径总和 II 从中序与后序遍历序列构造二叉树思路 513找树左下角的值 层序遍历法 使用层序遍历,找到最后一层最左边…...
使用 MMDetection 实现 Pascal VOC 数据集的目标检测项目练习(二) ubuntu的下载安装
首先,Linux系统是人工智能和深度学习首选系统。原因如下: 开放性和自由度:Linux 是一个开源操作系统,允许开发者自由修改和分发代码。这在开发和研究阶段非常有用,因为开发者可以轻松地访问和修改底层代码。社区支持:…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
