对于刚接触 Oracle 数据库的初学者来说,简单查询(如SELECT * FROM 表名)可能不难掌握,但面对复杂业务场景时,就需要更强大的查询能力。本文将围绕 Oracle 复杂查询的核心知识点展开,包括条件逻辑、分组函数、分组查询、子查询、分页及合并查询,用通俗的语言和实例帮你快速入门。

一、条件逻辑:让查询学会 “判断”

在 SQL 中,我们经常需要根据不同条件返回不同结果,这就需要用到条件逻辑。Oracle 中最常用的条件逻辑工具是CASE...WHEN语句,它类似其他编程语言中的if-else结构。

1️⃣逻辑判断 vs 条件判断

  • 逻辑判断:用ANDORNOT等逻辑运算符对条件表达式进行计算,最终返回truefalse(例如:sal > 1000 AND deptno = 20)。
  • 条件判断:根据条件决定执行哪个分支的操作(例如:“如果工资低于 1500,返回‘低’;否则返回‘高’”)。

2️⃣CASE...WHEN:两种实用形式

CASE...WHEN有两种形式,分别适用于不同场景:

(1)简单 CASE 表达式:匹配固定值

当需要将一个表达式的值与多个固定值对比时,用简单 CASE。

语法:

sql

CASE 表达式WHEN 值1 THEN 结果1WHEN 值2 THEN 结果2...ELSE 默认结果
END

实例:根据员工职位返回不同问候语

sql

SELECT EMPNO, ENAME, CASE job WHEN 'PRESIDENT' THEN '总裁辛苦了' WHEN 'MANAGER' THEN '经理好' WHEN 'ANALYST' THEN '组长干的不错' WHEN 'SALESMAN' THEN '跑业务去' WHEN 'CLERK' THEN '嗯' END 问候语 
FROM emp;
(2)搜索 CASE 表达式:处理复杂条件

当条件是范围、多字段组合等复杂逻辑时,用搜索 CASE。

语法:

sql

CASEWHEN 条件1 THEN 结果1WHEN 条件2 THEN 结果2...ELSE 默认结果
END

实例:根据工资范围划分等级

sql

SELECT EMPNO, ENAME, CASE WHEN sal < 1500 THEN 'Low' WHEN sal BETWEEN 1500 AND 2000 THEN 'Medium' WHEN sal > 2000 THEN 'High' ELSE 'Unknown' END AS salary_grade 
FROM emp;

二、分组函数:对数据 “汇总计算”

分组函数(又称聚合函数)用于对一组数据进行计算并返回单个结果,常与分组查询配合使用。核心注意点:分组函数不能直接与非分组字段同时出现在SELECT中(除非非分组字段在GROUP BY中)。

常用分组函数及实例

函数作用实例(基于 emp 表)
COUNT统计非空值的数量SELECT COUNT(sal) FROM emp;(统计有工资的员工数)
MIN求列的最小值SELECT MIN(sal) FROM emp;(查询最低工资)
MAX求列的最大值SELECT MAX(sal) FROM emp;(查询最高工资)
AVG求列的平均值(忽略 NULL)SELECT AVG(sal) FROM emp;(查询平均工资)

小提示:如果要包含 NULL 值计算(例如工资为 NULL 时按 0 处理),可结合NVL函数:AVG(NVL(sal, 0))

三、分组查询:按规则 “拆分数据”

当需要按某一列(如部门、职位)拆分数据并分别计算时,需用GROUP BY子句。

1️⃣GROUP BY 基础用法

语法:

sql

SELECT 分组字段, 分组函数
FROM 表名
GROUP BY 分组字段;

实例:

  • 按部门编号统计员工人数:

    sql

    SELECT deptno, COUNT(*) AS "人数" FROM emp GROUP BY deptno;
    
  • 按部门和职位统计人数(多字段分组):

    sql

    SELECT deptno, job, COUNT(*) FROM emp GROUP BY deptno, job ORDER BY deptno;
    

注意:GROUP BY后的字段可不包含在SELECT中(但通常会包含以便区分分组)。

2️⃣HAVING:对分组结果 “二次过滤”

HAVING子句用于过滤分组后的结果,与WHERE的区别如下:

特性WHEREHAVING
执行时机分组前过滤数据分组后过滤分组结果
能否用聚合函数不能

实例:

  • 查询员工人数大于 5 的部门:

    sql

    SELECT deptno, COUNT(*) FROM emp GROUP BY deptno HAVING COUNT(*) > 5;
    
  • 查询 20 号部门的最低工资(分组后过滤):

    sql

    SELECT MIN(sal) FROM emp GROUP BY deptno HAVING deptno = 20;
    

四、子查询:让查询 “嵌套起来”

当一次查询无法完成需求时(例如 “先查 A 的部门,再查该部门所有员工”),可以用子查询(嵌套在其他 SQL 中的SELECT语句)。

子查询的基本规则

  • 必须用括号()包裹;
  • 可嵌套多层;
  • 根据返回结果行数,分为单行、多行、多列子查询。

1️⃣单行子查询:返回 1 行结果

=><等运算符连接,适用于子查询结果唯一的场景。

实例:查询 SMITH 所在部门的所有员工

sql

SELECT ename, sal, deptno 
FROM emp 
WHERE deptno = (SELECT deptno FROM emp WHERE ename = 'SMITH');

2️⃣多行子查询:返回多行结果

需用INALLANY等运算符:

  • IN:匹配子查询结果中的任意一个值;
  • ALL:匹配子查询结果中的所有值;
  • ANY:匹配子查询结果中的任意一个值(与IN类似,但ANY可结合比较运算符)。

实例:

  • IN查询与 10 号部门工种相同的员工:

    sql

    SELECT ename, job, sal, deptno 
    FROM emp 
    WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno = 10);
    
  • ALL查询工资高于 30 号部门所有人的员工:

    sql

    SELECT ename, sal, deptno 
    FROM emp 
    WHERE sal > ALL (SELECT sal FROM emp WHERE deptno = 30);
    

    (等价于sal > (SELECT MAX(sal) FROM emp WHERE deptno = 30),效率更高)

3️⃣多列子查询:返回多列结果

当条件涉及多个字段时,用多列子查询。

实例:查询与 SMITH 同部门且同工种的员工

sql

SELECT ename, job, sal, deptno 
FROM emp 
WHERE (deptno, job) = (SELECT deptno, job FROM emp WHERE ename = 'SMITH');

4️⃣子查询的常见应用场景

  • 在 FROM 中使用:作为虚拟表(需指定别名),例如查询各部门中工资高于部门平均的员工:

    sql

    SELECT emp.deptno, ename, sal, dept.avgsal 
    FROM emp, (SELECT deptno, AVG(sal) AS avgsal FROM emp GROUP BY deptno) dept 
    WHERE emp.deptno = dept.deptno AND sal > dept.avgsal;
    
  • 在 DML 中使用:

    • 插入数据:INSERT INTO 表名 SELECT ...
    • 更新数据:UPDATE 表名 SET ... = (子查询)
    • 删除数据:DELETE FROM 表名 WHERE ... = (子查询)
  • 在 DDL 中使用:复制表结构和数据(加WHERE 1=2只复制结构):

    sql

    CREATE TABLE new_emp(id, name, sal, job, deptno) 
    AS SELECT empno, ename, sal, job, deptno FROM emp;
    

五、分页查询:批量数据 “分段显示”

Oracle 中通过伪列实现分页,常用的伪列有rownum(逻辑编号,从 1 开始)和rowid(物理编号)。其中rownum最常用。

rownum 分页的关键步骤

rownum的特性:总是从 1 开始编号,若结果集中没有rownum=1,则后续编号也不存在(因此不能直接用rownum >=6 AND rownum <=9)。

查询第 6-9 条记录的步骤:

  • 先获取前 10 条记录并编号:

    sql

    SELECT e.*, rownum rn FROM (SELECT * FROM emp) e WHERE rownum <= 10;
    
  • 嵌套查询,筛选编号大于 6 的记录:

    sql

    SELECT * FROM (SELECT e.*, rownum rn FROM (SELECT * FROM emp) e WHERE rownum <= 10
    ) WHERE rn > 6;
    

六、合并查询:多结果集 “组合运算”

UNIONUNION ALLINTERSECTMINUS组合多个查询结果,适用于大数据量场景。

操作符作用示例(查询工资 > 2500 或职位为 MANAGER 的员工)
UNION并集(去重)SELECT ... WHERE sal>2500 UNION SELECT ... WHERE job='MANAGER'
UNION ALL并集(不去重,效率更高)SELECT ... UNION ALL SELECT ...
INTERSECT交集(同时存在于两个结果集)SELECT ... INTERSECT SELECT ...
MINUS差集(存在于第一个集但不在第二个)SELECT ... MINUS SELECT ...

注意:组合的查询结果需列数相同、类型兼容;LOB、LONG 等特殊类型不支持部分操作符。

总结

Oracle 复杂查询是数据库操作的核心技能,本文涵盖了条件逻辑(CASE...WHEN)、分组函数、分组查询(GROUP BY+HAVING)、子查询、分页及合并查询等重点。初学者需注意:

  • 分组函数与GROUP BY的配合使用;
  • WHEREHAVING的区别;
  • 子查询的嵌套逻辑和rownum分页的特性。

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

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

相关文章

Redis-plus-plus API使用指南:通用操作与数据类型接口介绍

&#x1f351;个人主页&#xff1a;Jupiter.&#x1f680; 所属专栏&#xff1a;Redis 欢迎大家点赞收藏评论&#x1f60a;目录通用 API连接 Redis1. get/set2. exists 方法3. del 方法4. keys 方法5. expire 方法6. ttl 方法7. type 方法8. flushall 方法String 类型 API1. ge…

基于遗传编程的自动程序生成

这里写目录标题核心概念与工作原理1. 个体表示&#xff1a;树结构2. 初始化种群3. 适应度评估4. 选择5. 遗传操作&#xff08;繁殖&#xff09;6. 新一代种群形成7. 终止条件基于遗传编程的符号回归示例问题示例GP实现符号回归&#xff08;Deap&#xff09;GP实现符号回归&…

flowable汇总查询方式

背景&#xff1a;小程序开发申请流程。使用flowable流程框架。用户需要在后台统揽用户申请的汇总表。 设计思路&#xff1a;通过查询流程实例分页查询获取数据&#xff0c; 其中可以通过查询条件进行查询&#xff0c;查询条件是流程申请时添加到流程变量当中的&#xff0c;方便…

力扣438:找到字符串中所有的字母异位词

力扣438:找到字符串中所有的字母异位词题目思路代码题目 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 思路 我们先不看异位词这个条件&#xff0c;如何在字符串s中找到字符串p。我们可以…

ruoyi-vue(十一)——代码生成

大部分项目里其实有很多代码都是重复的&#xff0c;几乎每个基础模块的代码都有增删改查的功能&#xff0c;而这些功能都是大同小异&#xff0c; 如果这些功能都要自己去写&#xff0c;将会大大浪费我们的精力降低效率。所以这种重复性的代码可以使用代码生成。一 代码生成使用…

neo4j导入导出方法

在 Neo4j 中&#xff0c;如果需要将数据从 一个环境导出&#xff0c;再 导入到另一个环境&#xff08;如从开发环境迁移到生产环境&#xff09;&#xff0c;可以通过以下方法实现&#xff1a;方法 1&#xff1a;使用 neo4j-admin 导出和导入&#xff08;完整数据库迁移&#xf…

Diamond基础2:开发流程之LedDemo

文章目录1.关联VS Code2.Diamond工程目录3.Led Demo开发流程4.烧写bit文件5.传送门1.关联VS Code 和Vivado一样&#xff0c;Diamond也可以使用第三方的编辑器&#xff0c;VS Code编辑器因为可以安装各种插件&#xff0c;并且对verilog开发的支持也算完善&#xff0c;所以很受欢…

Golang 后台技术面试套题 1

文章目录1.网络1.1 浏览器从输入网址到展示页面&#xff0c;描述下整个过程&#xff1f;1.2 HTTP 502&#xff0c;503 和 504 是什么含义&#xff1f;区别以及如何排查&#xff1f;1.3 HTTPS 通信过程为什么要约定加密密钥 code&#xff0c;用非对称加密不行吗&#xff1f;1.4 …

【科研绘图系列】R语言绘制蝶形条形图蝶形柱状堆积图

文章目录 介绍 加载R包 数据下载 导入数据 数据预处理 画图 系统信息 参考 介绍 【科研绘图系列】R语言绘制蝶形条形图&蝶形柱状堆积图 加载R包 library(tidyverse) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2) library(grid

Jeecg后端经验汇总

Jeecg是一个不错的低代码平台&#xff0c;极大的降低了很多开发人员接私活的难度&#xff0c;也极大的降低了开发全套功能的难度。但是一码归一码&#xff0c;开发人员的水平很一般&#xff0c;如下&#xff1a;&#xff08;1&#xff09;普通用户可以修改管理员密码&#xff0…

ethernet_input到应用层处理简单分析

1、驱动层&#xff1a;从硬件读取数据并构造pbuf中断触发后&#xff0c;驱动层的接收任务&#xff08;或轮询函数&#xff09;会从网卡硬件读取数据&#xff0c;并将其封装为 LWIP 可识别的pbuf结构体&#xff08;LWIP 的数据缓冲区&#xff09;。关键函数&#xff1a;驱动自定…

C#WPF实战出真汁05--左侧导航

1、左侧导航设计要点清晰的信息架构 确保导航结构层次分明&#xff0c;主分类与子分类逻辑清晰&#xff0c;避免过度嵌套。使用分组、缩进或分隔线区分不同层级&#xff0c;保持视觉可读性。直观的图标与标签 为每个导航项搭配简洁的图标&#xff0c;强化视觉识别。标签文字需简…

大模拟 Major

题目来源&#xff1a;2025 Wuhan University of Technology Programming Contest 比赛链接&#xff1a;Dashboard - 2025 Wuhan University of Technology Programming Contest - Codeforces 题目大意&#xff1a; 模拟 16 支队伍的瑞士轮比赛结果&#xff0c;规则太多&…

【手撕JAVA多线程】1.从设计初衷去看JAVA的线程操作

目录 前言 概述 主动阻塞/唤醒 代码示例 实现 为什么必须在同步块中使用 计时等待是如何实现的 被动阻塞/唤醒 为什么要有被动阻塞/唤醒 实现&#xff08;锁升级&#xff09; 前言 JAVA多线程相关的内容很多很杂&#xff0c;但工作中用到的频率不高&#xff0c;用到…

UE5多人MOBA+GAS 46、制作龙卷风技能

文章目录创建龙卷风GA创建蒙太奇创捷一系列GE添加数据表添加到角色中创建龙卷风GA GA_Tornado 添加标签 // 龙卷风冷却CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Tornado_Cooldown)// 通用技能伤害CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Generic_Dama…

如何在ubuntu下安装libgpiod库

以下是关于如何在ubuntu下安装libgpiod库的两种安装方式以及遇到ubuntu存在多个工具链导致编译失败的解决方法。如果想要自由选择使用不同版本的libgpiod&#xff0c;可以选择手动编译安装方式&#xff0c;系统安装默认1.6.3版本(ubuntu22.04)。手动编译安装1、在github上下载要…

qt vs2019编译QXlsx

1、安装ActivePerl2、打开pro文件&#xff0c;直接编译即可第一个简单实例&#xff1a;#include "xlsxcellrange.h" #include "xlsxchart.h" #include "xlsxchartsheet.h" #include "xlsxdocument.h" #include "xlsxrichstring.h…

计算机存储器分类和层次结构详解

存储器是计算机系统的核心部件之一&#xff0c;其核心功能是存储程序&#xff08;指令&#xff09;和数据&#xff0c;是冯诺依曼体系结构“存储程序”概念的物质基础。它直接关系到计算机系统的性能、容量和成本。 存储器核心内容总览表分类维度存储器层级技术实现速度容量成本…

通过rss订阅小红书,程序员将小红书同步到自己的github主页

title: 通过rss订阅小红书&#xff0c;程序员将小红书同步到自己的github主页 tags: 个人成长 categories:杂谈最近在做一些新的尝试&#xff0c;把文本的内容转化为漫画和图片&#xff0c;方便大众阅读&#xff0c;恰好小红书很适合分发这些内容&#xff0c;于是我开通了小红书…

麒麟KylinOS V10-SP3 安装FastGPT

1. 操作系统环境CPU&#xff1a;20核 Xeon(R) Platinum 8457C 内存&#xff1a;64GB GPU&#xff1a;4090 操作系统&#xff1a;KylinOS-V10-SP32. 安装docker、docker-compose、fastgpt下载安装docker、docker-compose1. 下载docker docker 下载地址&#xff1a; https://do…