Oracle 数据库基础入门(四):分组与联表查询的深度探索(下)

news2025/3/7 2:09:12

在 Oracle 数据库的操作中,联合查询与子查询是获取复杂数据的关键手段。当单表数据无法满足业务需求时,联合查询允许我们从多张表中提取关联信息,而子查询则能以嵌套的方式实现更灵活的数据筛选。对于 Java 全栈开发者而言,掌握这些技术不仅能提升数据库操作能力,还能为构建高效的后端应用提供有力支持。

目录

二、联合查询

(一)联合查询的必要性与场景

(二)笛卡尔乘积

(三)三种联合查询方式

(四)练习题巩固

(五)三表联合查询

三、子查询

(一)子查询的概念与本质

(二)子查询的位置与应用

四、企业工作小技巧


二、联合查询

(一)联合查询的必要性与场景

联合查询在实际应用中极为常见,当我们需要整合来自多个表的数据时,它就派上了用场。比如在一个家庭信息管理系统中,若要查询丈夫信息的同时显示其妻子的名称;在学校管理系统中,查询学生时需要展示其所在班级;在教育选课系统中,查询选课时要同时呈现学生名称、课程名称以及课程分数。这些场景都需要联合查询来实现。

(二)笛卡尔乘积

笛卡尔乘积是理解联合查询的重要基础概念,它源自数学领域。假设有两个集合 X 和 Y,笛卡尔乘积就是将 X 集合中的每个元素与 Y 集合中的每个元素进行组合,组合的总数为 X 集合元素个数乘以 Y 集合元素个数。例如,若 X = {1, 2},Y = {a, b},那么它们的笛卡尔乘积为 {(1, a), (1, b), (2, a), (2, b)}。在数据库中,当我们对两张表进行无条件的联合操作时,就会得到笛卡尔乘积结果。但通常笛卡尔乘积的结果集非常庞大,且包含大量无意义的数据,所以需要通过等值判断等方式对其进行筛选,以获取我们真正需要的数据。

(三)三种联合查询方式

  1. 左外连接(left join)
    • 语法与示例:以左表为基准,返回左表中的所有记录以及右表中满足连接条件的记录。若右表中无匹配记录,则对应字段值为 NULL。例如,查询所有学生及其班级信息(适合查看哪些学员分配了班级,哪些学员未分配班级):
select
    s.id,
    s.stu_name,
    c.class_name 
from
    students s
    left join class_info c on s.fk_class_id = c.id;
  • Java 全栈关联:在 Java 全栈开发的学校管理系统中,后端使用 Java 代码连接数据库执行此查询。通过 MyBatis 或 Hibernate 等框架,将查询结果映射为 Java 对象,如StudentWithClass对象,包含学生 ID、姓名和班级名称属性。前端可以通过 RESTful API 获取这些数据,以表格或列表形式展示给用户,方便管理员查看学生的班级分配情况。

  1. 右外连接(right join)
    • 语法与示例:与左外连接相反,以右表为基准,返回右表中的所有记录以及左表中满足连接条件的记录。若左表中无匹配记录,则对应字段值为 NULL。例如,查询所有班级及其包含的学生信息(适合查看哪些班有学员,哪些班没有学员):
select
    s.id,
    s.stu_name,
    c.class_name 
from
    students s
    right join class_info c on s.fk_class_id = c.id;

  • Java 全栈关联:在 Java 开发的类似系统中,该查询结果可用于生成班级人员统计报表。后端将结果处理后传递给前端,前端利用图表库(如 Echarts)将数据可视化,以直观展示每个班级的学生分布情况。

  1. 内连接(inner join)
    • 语法与示例:只返回两张表中满足连接条件的记录。有两种常见写法,例如:
-- 内联查(一)
select
    s.id,
    s.stu_name,
    c.class_name 
from
    students s
    inner join class_info c on s.fk_class_id = c.id;
-- 内联查(二)
select
    s.id,
    s.stu_name,
    c.class_name 
from
    students s, class_info c where s.fk_class_id = c.id;

  • Java 全栈关联:在电商系统中,若要查询已下单的用户及其订单信息,可使用内连接。后端通过 Java 代码执行查询,将结果用于订单处理流程,如计算订单总价、更新库存等操作。前端则可展示订单详情页面,让用户确认订单信息。

在企业开发中,左外联合查询和内联合查询应用最为广泛。因为左外连接能保留左表所有数据,适用于需要全面展示某一方数据及其关联信息的场景;内连接则专注于获取有实际关联的数据,常用于查询相互匹配的数据对。

(四)练习题巩固

  1. 部门与职员表操作
    • 建表与插入数据
-- 创建部门表
CREATE TABLE Departments (
    ID NUMBER PRIMARY KEY,
    DepartmentName NVARCHAR2(100) NOT NULL
);
-- 创建职员表
CREATE TABLE Employees (
    ID NUMBER PRIMARY KEY,
    EmployeeName VARCHAR2(100) NOT NULL,
    Position VARCHAR2(100),
    Salary NUMBER,
    DepartmentID NUMBER,
    CONSTRAINT fk_department FOREIGN KEY(DepartmentID) REFERENCES Departments(ID)
);
-- 插入部门数据
INSERT INTO Departments (ID,DepartmentName) VALUES (1,'研发部');
INSERT INTO Departments (ID,DepartmentName) VALUES (2,'市场部');
-- 创建职员表的序列
CREATE SEQUENCE seq_employees
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;
-- 插入员工数据
INSERT INTO Employees (ID, EmployeeName, Position, Salary, DepartmentID) VALUES (seq_employees.NEXTVAL, '张三', '高级工程师', 8000, 1);
INSERT INTO Employees (ID, EmployeeName, Position, Salary, DepartmentID) VALUES (seq_employees.NEXTVAL, '李四', '产品经理', 7500, 1);
INSERT INTO Employees (ID, EmployeeName, Position, Salary, DepartmentID) VALUES (seq_employees.NEXTVAL, '王五', '销售经理', 6000, 2);
INSERT INTO Employees (ID, EmployeeName, Position, Salary, DepartmentID) VALUES (seq_employees.NEXTVAL, '赵六', '市场营销', 5500, 2);
INSERT INTO Employees (ID, EmployeeName, Position, Salary, DepartmentID) VALUES (seq_employees.NEXTVAL, '孙七', '实习生', 3000, 2);

  • 查询需求
    • 查询所有职员信息,并显示其部门名称:
select e.ID, e.EmployeeName, d.DepartmentName
from Employees e
left join Departments d on e.DepartmentID = d.ID;

  • 查询工资高于 6K 以上的职员,显示其部门名称:
select e.ID, e.EmployeeName, d.DepartmentName
from Employees e
left join Departments d on e.DepartmentID = d.ID
where e.Salary > 6000;

  • 查询研发部下,都有哪些职员:
select e.ID, e.EmployeeName
from Employees e
left join Departments d on e.DepartmentID = d.ID
where d.DepartmentName = '研发部';

  • Java 全栈关联:在企业人力资源管理系统中,这些查询结果可用于生成员工报表、薪资统计分析等功能。后端 Java 代码调用数据库执行查询,将结果封装成 Java 对象,如EmployeeWithDepartment对象,传递给前端展示。前端可以提供筛选、排序等交互功能,方便 HR 人员查看和分析数据。

  1. 学生与班级表操作
    • 分组统计不同班级人数
SELECT
    c.CLASS_NAME,
    count( * ) 
FROM
    students s
    LEFT JOIN class_info c ON s.FK_CLASS_ID = c.id 
GROUP BY
    c.CLASS_NAME;

  • 查询班级人数大于 0 的班级
SELECT
    c.CLASS_NAME,
    count( s.id ) total 
FROM
    students s
    RIGHT JOIN class_info c ON s.FK_CLASS_ID = c.id 
GROUP BY
    c.CLASS_NAME 
HAVING
    count( s.id ) > 0 
ORDER BY
    total DESC;
  • Java 全栈关联:在学校教务管理系统中,这些统计数据可用于班级规模分析、资源分配等决策。后端将查询结果通过 Java 代码处理后,提供给前端生成柱状图或饼状图,直观展示班级人数分布情况。

  1. 车辆相关表操作
    • 建表与插入数据
CREATE TABLE vehicle_types (
    id NUMBER PRIMARY KEY,       -- 车辆类型ID,主键
    type_name VARCHAR2(100) NOT NULL  -- 车辆类型名称,不允许为空
);
CREATE TABLE vehicles (
    id NUMBER PRIMARY KEY,    -- 车辆ID,主键
    license_no VARCHAR2(20) NOT NULL, -- 车牌号,不允许为空
    model VARCHAR2(50) NOT NULL,     -- 车型,不允许为空
    fk_type_id NUMBER NOT NULL,          -- 车辆类型ID,外键
    owner_name VARCHAR2(100),         -- 车主姓名
    CONSTRAINT fk_vehicle_type FOREIGN KEY (fk_type_id) REFERENCES vehicle_types(id) -- 外键约束
);
INSERT INTO vehicle_types (id, type_name)
VALUES (1, '轿车');
INSERT INTO vehicle_types (id, type_name)
VALUES (2, 'SUV');
INSERT INTO vehicle_types (id, type_name)
VALUES (3, '卡车');
-- 插入车辆数据
INSERT INTO vehicles (id, license_no, model, fk_type_id, owner_name)
VALUES (1, '沪A12345', '卡罗拉', 1, '张三');
INSERT INTO vehicles (id, license_no, model, fk_type_id, owner_name)
VALUES (2, '京B67890', 'X5', 2, '李四');
INSERT INTO vehicles (id, license_no, model, fk_type_id, owner_name)
VALUES (3, '粤C24680', 'F-150', 3, '王五');

  • 查询需求
    • 查询所有的车辆,并显示其车辆类型:
select v.id, v.license_no, vt.type_name
from vehicles v
left join vehicle_types vt on v.fk_type_id = vt.id;

  • 查询车辆类型是 “轿车” 的车辆:
select v.id, v.license_no, vt.type_name
from vehicles v
left join vehicle_types vt on v.fk_type_id = vt.id
where vt.type_name = '轿车';

  • 按照车辆类型分组统计下,不同的车辆类型各自有多少辆车:
select vt.type_name, count(*)
from vehicles v
left join vehicle_types vt on v.fk_type_id = vt.id
group by vt.type_name;
  • Java 全栈关联:在汽车租赁管理系统中,这些查询结果可用于车辆库存管理、车型统计分析等功能。后端 Java 代码处理查询结果,前端展示车辆列表、车型占比等信息,方便管理员进行车辆调度和采购决策。

(五)三表联合查询

在企业开发中,一般不建议联合查询超过三张表。因为随着表的增加,笛卡尔乘积会导致数据量呈指数级增长,严重影响查询性能。例如,在一个学校选课系统中,若要查询每个学生的选课情况,涉及学生表、选课关系表和课程表:

create table course_info(
    id number(11) primary key,
    course_name nvarchar2(20),
    score number(1)
);
create table stu_course_info(
    id number(11) primary key,
    fk_stu_id number(11),
    fk_course_id number(11)
);
SELECT
    s.id,
    s.STU_NAME,
    c.course_name,
    c.score 
FROM
    students s
    LEFT JOIN stu_course_info sc ON sc.FK_STU_ID = s.id
    LEFT JOIN course_info c ON sc.fk_course_id = c.id;

若要查询选择 “音乐鉴赏” 的学生:

SELECT
    s.id,
    s.STU_NAME,
    c.course_name,
    c.score 
FROM
    students s
    LEFT JOIN stu_course_info sc ON sc.FK_STU_ID = s.id
    LEFT JOIN course_info c ON sc.fk_course_id = c.id
where c.course_name = '音乐鉴赏';

在 Java 全栈开发中,处理三表联合查询时,后端开发人员需要谨慎优化查询语句,如合理使用索引、避免不必要的字段选择等。同时,前端在展示大量数据时,也需要采用分页、懒加载等技术,以提升用户体验。

三、子查询

(一)子查询的概念与本质

子查询是一种特殊的联合查询方式,其本质是在一个 SQL 查询语句中嵌套另一个 SQL 查询语句,就像俄罗斯套娃一样。例如,查询语文考试成绩比语文平均分还低的学员:

SELECT
    id,
    name,
    score 
FROM
    student_exam_info 
WHERE
    subject = '语文' 
    AND score <= ( SELECT avg( score ) FROM student_exam_info WHERE subject = '语文' );

子查询可以放置在select后面、from后面以及where后面,不同位置的子查询具有不同的特点和用途。

(二)子查询的位置与应用

  1. select 后面的子查询
    • 特点与示例:此类子查询返回单行、单列数据。例如,查询学生 id、学生名称以及班级名称(通过子查询替代外键直接关联查询):
SELECT
    id,
    stu_name,
    ( SELECT class_name FROM class_info WHERE id = fk_class_id ) class_name 
FROM
    students;

  • Java 全栈关联:在 Java 开发的小型信息管理系统中,当需要展示学生及其班级信息时,后端执行此查询。将查询结果映射为 Java 对象后传递给前端,前端可以在学生信息展示页面中,将班级名称与学生其他信息一同呈现,方便用户查看。
  1. from 后面的子查询
    • 特点与示例:子查询的结果被视为一张表。例如,查询所有男学生及其班级名称:
SELECT
    s.id,
    s.stu_name,
    class_name 
FROM
    ( SELECT * FROM students WHERE gender = '男' ) s
    LEFT JOIN class_info c ON s.FK_CLASS_ID = c.id;
  • Java 全栈关联:在学校的学生统计模块中,后端利用此查询获取男学生及其班级信息。将结果处理后,前端可以生成男学生班级分布报表,以图表形式展示不同班级男学生的数量。
  1. where 后面的子查询:如前面提到的查询语文成绩低于平均分的学员示例,通过子查询先计算出语文平均分,再在主查询中筛选出符合条件的学员。在 Java 全栈开发的成绩分析系统中,这种查询可用于生成成绩分析报告,帮助教师了解学生成绩分布情况,为教学改进提供依据。

四、企业工作小技巧

  1. 优化联合查询性能
    • 合理使用索引:在联合查询涉及的表中,为连接字段创建索引可以显著提升查询速度。例如,在学生表和班级表通过fk_class_id进行连接时,为fk_class_id字段创建索引,能加快数据匹配速度。但要注意,索引并非越多越好,过多索引会增加数据插入和更新的时间成本。
    • 减少笛卡尔乘积影响:在进行联合查询时,确保连接条件准确且充分,避免产生不必要的笛卡尔乘积。例如,明确指定学生表和班级表之间的连接条件为students.fk_class_id = class_info.id,防止出现大量无意义的组合数据。
  2. 子查询的优化与使用
    • 避免多层嵌套:尽量减少子查询的嵌套层数,因为过多的嵌套会使查询语句复杂难懂,且性能下降。如果可能,将多层子查询转换为联合查询或使用临时表来优化。
    • 利用子查询的原子性:子查询可以将复杂的查询逻辑拆分成多个原子部分,方便理解和维护。例如,在复杂的数据分析查询中,先通过子查询计算出一些中间结果,再在主查询中使用这些结果进行最终筛选。
  3. Java 全栈开发中的数据处理
    • 前后端数据传输优化:在 Java 全栈开发中,联合查询和子查询返回的数据量可能较大。前端在接收数据时,要采用合适的数据传输格式(如 JSON),并进行必要的压缩。后端可以对查询结果进行分页处理,减少一次性传输的数据量,提升系统响应速度。
    • 业务逻辑与查询结合:不要单纯依赖数据库查询来完成所有业务逻辑。在 Java 代码中进行一些数据处理和逻辑判断,例如对查询结果进行二次筛选、计算等操作,这样可以减轻数据库负担,同时增强系统的灵活性和可维护性。

通过深入学习联合查询和子查询,我们在 Oracle 数据库操作能力上又迈出了重要一步。在未来的 Java 全栈开发工作中,灵活运用这些技术将帮助我们高效地处理复杂的数据需求,为企业构建强大的数据驱动应用。

查看分组基础查询&复合分组&having过滤请点击查看剩余部分

               Oracle 数据库基础入门(四):分组与联表查询的深度探索(上)-CSDN博客                

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

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

相关文章

MacBook上API调⽤⼯具推荐

在当今的软件开发中&#xff0c;API调用工具已经成为了开发者不可或缺的助手。无论是前端、后端还是全栈开发&#xff0c;API的调试、测试和管理都是日常工作中的重要环节。想象一下&#xff0c;如果没有这些工具&#xff0c;开发者可能需要手动编写复杂的CURL命令&#xff0c;…

【数据结构】LRUCache|并查集

目录 一、LRUCache 1.概念 2.实现:哈希表双向链表 3.JDK中类似LRUCahe的数据结构LinkedHashMap &#x1f525;4.OJ练习 二、并查集 1. 并查集原理 2.并查集代码实现 3.并查集OJ 一、LRUCache 1.概念 最近最少使用的&#xff0c;一直Cache替换算法 LRU是Least Recent…

初识Qt · 信号与槽 · 基础知识

目录 前言&#xff1a; 信号和槽初识 两个问题 前言&#xff1a; 本文我们正式开始介绍信号与槽这个概念&#xff0c;在谈及Qt中的信号与槽这个概念之前&#xff0c;我们不妨回顾一下Linux中的信号&#xff0c;比如发生了除0错误&#xff0c;OS就会给该进程发送一个信号&am…

Java高频面试之集合-03

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;说说ArrayList和LinkedList的区别 ArrayList 与 LinkedList 的详细对比 一、底层数据结构 特性ArrayListLinkedList存…

宇树科技再落一子!天羿科技落地深圳,加速机器人创世纪

2025年3月5日&#xff0c;机器人行业龙头宇树科技&#xff08;Unitree&#xff09;在深圳再添新动作——全资子公司深圳天羿科技有限公司正式成立。这家注册资本10万元、法定代表人周昌慧的新公司&#xff0c;聚焦智能机器人研发与销售&#xff0c;标志着宇树科技在华南市场的战…

【长安大学】苹果手机/平板自动连接认证CHD-WIFI脚本(快捷指令)

背景&#xff1a; 已经用这个脚本的记得设置Wifi时候&#xff0c;关闭“自动登录” 前几天实在忍受不了CHD-WIFI动不动就断开&#xff0c;一天要重新连接&#xff0c;点登陆好几次。试了下在网上搜有没有CHD-WIFI的自动连接WIFI自动认证脚本&#xff0c;那样我就可以解放双手&…

计算机毕业设计SpringBoot+Vue.js电商平台(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【杂谈】信创电脑华为w515(统信系统)登录锁定及忘记密码处理

华为w515麒麟芯片版&#xff0c;还有非麒麟芯片版本&#xff0c;是一款信创电脑&#xff0c;一般安装的UOS系统。 准备一个空U盘&#xff0c;先下载镜像文件及启动盘制作工具&#xff0c;连接如下&#xff1a; 百度网盘 请输入提取码 http://livecd.uostools.com/img/apps/l…

初始提示词(Prompting)

理解LLM架构 在自然语言处理领域&#xff0c;LLM&#xff08;Large Memory Language Model&#xff0c;大型记忆语言模型&#xff09;架构代表了最前沿的技术。它结合了存储和检索外部知识的能力以及大规模语言模型的强大实力。 LLM架构由外部记忆模块、注意力机制和语…

Vue+el-upload配置minIO实现大文件的切片并发上传、上传进度展示、失败重试功能

vue3el-upload实现切片上传 效果图 初始界面 上传中的界面 上传完成的界面 上传失败的界面 <template><div><el-uploadclass"BigFileUpload"ref"uploadRef"action"#"drag:show-file-list"false":on-change"…

正则表达式梳理(基于python)

正则表达式&#xff08;regular expression&#xff09;是一种针对字符串匹配查找所定义的规则模式&#xff0c;独立于语言&#xff0c;但不同语言在实现上也会存在一些细微差别&#xff0c;下面基于python对常用的相关内容进行梳理。 文章目录 一、通用常识1.通配符ps.反义 2.…

【仿muduo库one thread one loop式并发服务器实现】

文章目录 一、项目介绍1-1、项目总体简介1-2、项目开发环境1-3、项目核心技术1-4、项目开发流程1-5、项目如何使用 二、框架设计2-1、功能模块划分2-1-1、SERVER模块2-1-2、协议模块 2-2、项目蓝图2-2-1、整体图2-2-2、模块关系图2-2-2-1、Connection 模块关系图2-2-2-2、Accep…

服务流程设计和服务或端口重定向及其websocket等应用示例

服务流程设计和服务或端口重定向及其websocket等应用示例 目录 服务或端口重定向的服务设计和websocket等应用示例 一、通用请求控制流程 1.1、入口 1.2、所有GET请求首先预检控制单元 1.3、http请求会分别自动307重定向 1.4、所有请求首先执行跨源控制单元 1.5、然后…

【数据库】关系代数

关系代数 一、关系代数的概念二、关系代数的运算2.1 并、差、交2.2 投影、选择2.3 笛卡尔积2.4 连接2.5 重命名2.6 优先级 一、关系代数的概念 关系代数是一种抽象的数据查询语言用对关系的运算来表达查询 运算对象&#xff1a;关系运算符&#xff1a;4类运算结果&#xff1a;…

ubuntu20 安装python2

1. 确保启用了 Universe 仓库 在某些情况下&#xff0c;python2-minimal 包可能位于 Universe 仓库中。你可以通过以下命令启用 Universe 仓库并更新软件包列表&#xff1a; bash复制 sudo add-apt-repository universe sudo apt update 然后尝试安装&#xff1a; bash复制…

MySQL无法连接到本地localhost的解决办法2024.11.8

问题描述&#xff1a;我的MySQL可以远程连接服务器&#xff0c;但无法连接自己的localhost。 错误提示&#xff1a; 2003 - Cant connet to MySQL server on localhost(10061 "Unknown error")查找问题原因&#xff1a; 1. 检查环境变量是否正确&#xff1a;发现没…

最新Spring Security实战教程(一)初识Spring Security安全框架

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Micro麦可乐的博客 &#x1f425;《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程&#xff0c;入门到实战 &#x1f33a;《RabbitMQ》…

告别GitHub连不上!一分钟快速访问方案

一、当GitHub抽风时&#xff0c;你是否也这样崩溃过&#xff1f; &#x1f621; npm install卡在node-sass半小时不动&#x1f62d; git clone到90%突然fatal: early EOF&#x1f92c; 改了半天hosts文件&#xff0c;第二天又失效了... 根本原因&#xff1a;传统代理需要复杂…

Leetcode 1477. 找两个和为目标值且不重叠的子数组 前缀和+DP

原题链接&#xff1a; Leetcode 1477. 找两个和为目标值且不重叠的子数组 class Solution { public:int minSumOfLengths(vector<int>& arr, int target) {int narr.size();int sum0;int maxnINT_MAX;vector<int> dp(n,maxn);//dp[i]表示以索引i之前的满足要求…

R语言绘图:韦恩图

韦恩分析 韦恩分析&#xff08;Venn Analysis&#xff09;常用于可视化不同数据集之间的交集和并集。维恩图&#xff08;Venn diagram&#xff09;&#xff0c;也叫文氏图、温氏图、韦恩图、范氏图&#xff0c;用于显示元素集合重叠区域的关系型图表&#xff0c;通过图形与图形…