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

在 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博客                

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

常用的AI文本大语言模型汇总

AI文本【大语言模型】 1、文心一言https://yiyan.baidu.com/ 2、海螺问问https://hailuoai.com/ 3、通义千问https://tongyi.aliyun.com/qianwen/ 4、KimiChat https://kimi.moonshot.cn/ 5、ChatGPThttps://chatgpt.com/ 6、魔塔GPT https://www.modelscope.cn/studios/iic…

GPIO概念

GPIO通用输入输出口 在芯片内部存在多个GPIO&#xff0c;每个GPIO用于管理多个芯片进行输入&#xff0c;输出工作 引脚电平 0v ~3.3v&#xff0c;部分引脚可容任5v 输出模式下可控制端口输出高低电平&#xff0c;可以驱动LED&#xff0c;控制蜂鸣器&#xff0c;模拟通信协议&a…

论文笔记-NeurIPS2017-DropoutNet

论文笔记-NeurIPS2017-DropoutNet: Addressing Cold Start in Recommender Systems DropoutNet&#xff1a;解决推荐系统中的冷启动问题摘要1.引言2.前言3.方法3.1模型架构3.2冷启动训练3.3推荐 4.实验4.1实验设置4.2在CiteULike上的实验结果4.2.1 Dropout率的影响4.2.2 实验结…

在 Mac mini M2 上本地部署 DeepSeek-R1:14B:使用 Ollama 和 Chatbox 的完整指南

随着人工智能技术的飞速发展&#xff0c;本地部署大型语言模型&#xff08;LLM&#xff09;已成为许多技术爱好者的热门选择。本地部署不仅能够保护隐私&#xff0c;还能提供更灵活的使用体验。本文将详细介绍如何在 Mac mini M2&#xff08;24GB 内存&#xff09;上部署 DeepS…

530 Login fail. A secure connection is requiered(such as ssl)-java发送QQ邮箱(简单配置)

由于cs的csdN许多文章关于这方面的都是vip文章&#xff0c;而本文是免费的&#xff0c;希望广大网友觉得有帮助的可以多点赞和关注&#xff01; QQ邮箱授权码到这里去开启 授权码是16位的字母&#xff0c;填入下面的mail.setting里面的pass里面 # 邮件服务器的SMTP地址 host…

经验分享:用一张表解决并发冲突!数据库事务锁的核心实现逻辑

背景 对于一些内部使用的管理系统来说&#xff0c;可能没有引入Redis&#xff0c;又想基于现有的基础设施处理并发问题&#xff0c;而数据库是每个应用都避不开的基础设施之一&#xff0c;因此分享个我曾经维护过的一个系统中&#xff0c;使用数据库表来实现事务锁的方式。 之…

【 实战案例篇三】【某金融信息系统项目管理案例分析】

大家好,今天咱们来聊聊金融行业的信息系统项目管理。这个话题听起来可能有点专业,但别担心,我会尽量用大白话给大家讲清楚。金融行业的信息系统项目管理,说白了就是如何高效地管理那些复杂的IT项目,确保它们按时、按预算、按质量完成。咱们今天不仅会聊到一些理论,还会通…

爬虫系列之发送请求与响应《一》

一、请求组成 1.1 请求方式&#xff1a;GET和POST请求 GET:从服务器获取&#xff0c;请求参数直接附在URL之后&#xff0c;便于查看和分享&#xff0c;常用于获取数据和查询操作 POST&#xff1a;用于向服务器提交数据&#xff0c;其参数不会显示在URL中&#xff0c;而是包含在…

最新最详细的配置Node.js环境教程

配置Node.js环境 一、前言 &#xff08;一&#xff09;为什么要配置Node.js&#xff1f;&#xff08;二&#xff09;NPM生态是什么&#xff08;三&#xff09;Node和NPM的区别 二、如何配置Node.js环境 第一步、安装环境第二步、安装步骤第三步、验证安装第四步、修改全局模块…

题解 | 牛客周赛83 Java ABCDEF

目录 题目地址 做题情况 A 题 B 题 C 题 D 题 E 题 F 题 牛客竞赛主页 题目地址 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 做题情况 A 题 输出两个不是同一方位的字符中的任意一个就行 import java.io.*; import java.math.*; import java…

netty如何处理粘包半包

文章目录 NIO中存在问题粘包半包滑动窗口MSS 限制Nagle 算法 解决方案 NIO中存在问题 粘包 现象&#xff0c;发送 abc def&#xff0c;接收 abcdef原因 应用层&#xff1a;接收方 ByteBuf 设置太大&#xff08;Netty 默认 1024&#xff09;滑动窗口&#xff1a;假设发送方 25…

【Linux】I/O操作

目录 1. 整体学习思维导图 2. 理解文件 2.1 文件是什么&#xff1f; 2.2 回顾C语言库函数的文件操作 2.3 stdin/stdout/stderr 2.4 系统的文件I/O操作 2.4.1 了解位图标记位方法(宏) 2.4.2 认识系统I/O常用调用接口 2.5 对比C文件操作函数和系统调用函数 2.5.1 fd是什么…

ISP CIE-XYZ色彩空间

1. 颜色匹配实验 1931年&#xff0c;CIE综合了前人实验数据&#xff0c;统一采用700nm&#xff08;红&#xff09;、546.1nm&#xff08;绿&#xff09;、435.8nm&#xff08;蓝&#xff09;​作为标准三原色波长&#xff0c;绘制了色彩匹配函数&#xff0c;如下图。选定这些波…

5G学习笔记之BWP

我们只会经历一种人生&#xff0c;我们选择的人生。 参考&#xff1a;《5G NR标准》、《5G无线系统指南:如微见著&#xff0c;赋能数字化时代》 目录 1. 概述2. BWP频域位置3. 初始与专用BWP4. 默认BWP5. 切换BWP 1. 概述 在LTE的设计中&#xff0c;默认所有终端均能处理最大2…

计算机毕业设计SpringBoot+Vue.js智能无人仓库管理系统(源码+文档+PPT+讲解)

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

qt-C++笔记之QToolButton和QPushButton的区别

qt-C笔记之QToolButton和QPushButton的区别 code review! 文章目录 qt-C笔记之QToolButton和QPushButton的区别1.运行2.main.cpp3.main.pro 1.运行 QToolButton 适用于工具栏或需要较紧凑、图标化显示的场合。通过 setAutoRaise(true) 与 setToolButtonStyle(Qt::ToolButtonTe…

[含文档+PPT+源码等]精品基于Python实现的vue3+Django计算机课程资源平台

基于Python实现的Vue3Django计算机课程资源平台的背景&#xff0c;可以从以下几个方面进行阐述&#xff1a; 一、教育行业发展背景 1. 教育资源数字化趋势 随着信息技术的快速发展&#xff0c;教育资源的数字化已成为不可逆转的趋势。计算机课程资源作为教育领域的重要组成部…

项目准备(flask+pyhon+MachineLearning)- 3

目录 1.商品信息 2. 商品销售预测 2.1 机器学习 2.2 预测功能 3. 模型评估 1.商品信息 app.route(/products) def products():"""商品分析页面"""data load_data()# 计算当前期间和上期间current_period data[data[成交时间] > data[成…

老牌工具,16年依然抗打!

在电脑还没普及、操作系统为Windows XP/7的时代&#xff0c;多媒体文件的转换操作常常面临格式不兼容的问题。这时一款名为格式工厂的软件成为了众多用户的首选工具。格式工厂以其简洁易用的界面和强大的功能&#xff0c;轻松地进行各种文件格式的转换。成为很多修小伙伴的喜爱…

LM studio 加载ollama的模型

1.LM 下载&#xff1a; https://lmstudio.ai/ 2.ollama下载&#xff1a; https://ollama.com/download 3.打开ollama&#xff0c;下载deepseek-r1。 本机设备资源有限&#xff0c;选择7B的&#xff0c;执行ollama run deepseek-r1:7b 4.windows chocolatey下载&#xff1a; P…