MySQL 复合查询

news2024/12/26 17:54:39
实际开发中往往数据来自不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张表EMP,DEPT,SALGRADE 来演示如何进行多表查询。表结构的代码以及插入的数据如下:
DROP database IF EXISTS `scott`;
CREATE database IF NOT EXISTS `scott` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

USE `scott`;

DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `deptno` int(2) unsigned zerofill NOT NULL COMMENT '部门编号',
  `dname` varchar(14) DEFAULT NULL COMMENT '部门名称',
  `loc` varchar(13) DEFAULT NULL COMMENT '部门所在地点'
);


DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (
  `empno` int(6) unsigned zerofill NOT NULL COMMENT '雇员编号',
  `ename` varchar(10) DEFAULT NULL COMMENT '雇员姓名',
  `job` varchar(9) DEFAULT NULL COMMENT '雇员职位',
  `mgr` int(4) unsigned zerofill DEFAULT NULL COMMENT '雇员领导编号',
  `hiredate` datetime DEFAULT NULL COMMENT '雇佣时间',
  `sal` decimal(7,2) DEFAULT NULL COMMENT '工资月薪',
  `comm` decimal(7,2) DEFAULT NULL COMMENT '奖金',
  `deptno` int(2) unsigned zerofill DEFAULT NULL COMMENT '部门编号'
);


DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade` (
  `grade` int(11) DEFAULT NULL COMMENT '等级',
  `losal` int(11) DEFAULT NULL COMMENT '此等级最低工资',
  `hisal` int(11) DEFAULT NULL COMMENT '此等级最高工资'
);


insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept (deptno, dname, loc)
values (20, 'RESEARCH', 'DALLAS');
insert into dept (deptno, dname, loc)
values (30, 'SALES', 'CHICAGO');
insert into dept (deptno, dname, loc)
values (40, 'OPERATIONS', 'BOSTON');

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, null, 20);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, null, 30);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, null, 10);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, null, 20);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7839, 'KING', 'PRESIDENT', null, '1981-11-17', 5000, null, 10);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7844, 'TURNER', 'SALESMAN', 7698,'1981-09-08', 1500, 0, 30);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, null, 20);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, null, 30);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, null, 20);

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 10);

insert into salgrade (grade, losal, hisal) values (1, 700, 1200);
insert into salgrade (grade, losal, hisal) values (2, 1201, 1400);
insert into salgrade (grade, losal, hisal) values (3, 1401, 2000);
insert into salgrade (grade, losal, hisal) values (4, 2001, 3000);
insert into salgrade (grade, losal, hisal) values (5, 3001, 9999);

可以看到有三张表部门表dept,员工表emp,工资等级表salgrade。

多表查询

在MySQL中,多表查询是指在一个查询中涉及到两个或更多的表。这种查询通常用于从多个相关的数据表中检索数据。多表查询的关键在于使用连接条件来关联不同表中的数据。

内连接

内连接(Inner Join)是一种SQL操作,用于从两个或多个表中检索相关数据。内连接通过在连接条件满足的情况下返回两个表中匹配的行。内连接仅返回那些在连接条件下有匹配的行,其他不匹配的行将被排除。

select 列名1,列名2 from 表名1 inner join 表名2 on 条件;

以上为内连接的标准写法,还有以下写法和内连接得到的效果一致,更简单。

select 列名1,列名2... from 表名1,表名2... where 条件;
显示雇员名、雇员工资以及所在部门的名字
  因为上面的数据来自 EMP DEPT 表,因此要联合查询
写法一
select emp.ename,emp.sal,dept.dname from emp inner join dept on emp.deptno=dept.deptno;

写法二

select emp.ename,emp.sal,dept.dname from emp,dept where emp.deptno=dept.deptno;

左外连接

select 列名1,列名2... from 表名1 left join 表名2 on 条件;

左外连接(Left Join)是一种SQL操作,用于从两个或多个表中检索相关数据。左外连接返回左表中的所有记录,以及右表中与左表匹配的记录,如果右表中没有匹配项,左表的记录仍然会被返回,但右表的字段会显示为 NULL。

现在创建两张表学生表stu和成绩表exam,并插入数据,其代码如下:

create table stu (id int, name varchar(30)); -- 学生表
insert into stu values(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
create table exam (id int, grade int); -- 成绩表
insert into exam values(1, 56),(2,76),(11, 8);
查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来
select * from stu left join exam on stu.id=exam.id;

右外连接

右外连接(Right Join)是一种SQL操作,用于从两个或多个表中检索相关数据。右外连接返回右表中的所有记录,以及左表中与右表匹配的记录。如果左表中没有匹配项,左表的字段会显示为 NULL。

select 列名1,列名2... from 表名1 right join 表名2 on 条件;
stu 表和 exam 表联合查询,把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要
显示出来
select * from stu right join exam on stu.id=exam.id;

自连接

自连接是一种特殊的多表查询,可以理解为自己与自己之间进行多表查询。

select 列名1,列名2... from 表名 as 别名1, 表名 as 别名2;
显示上级领导的编号和姓名(mgr 是员工领导的编号 --empno
select distinct leader.empno,leader.ename from emp leader,emp worker where worker.mgr=leader.empno;

子查询

子查询(Sub Query)是指在一个查询语句中嵌套另一个查询语句,其中内层查询的结果作为外层查询的条件或数据来源。子查询也被称为嵌套查询或内层查询,而包含子查询的查询语句被称为外层查询或父查询。

单行子查询

select ... from ... where 列名 = (select ... from ...);
显示 SMITH 同一部门的员工
select * from dept=(select deptno from emp where ename='smith');

多行子查询

select ... from ... where 列名 in (select ... from ...);
select ... from ... where 列名 比较操作符 all(select ... from ...);
select ... from ... where 列名 比较操作符 any(select ... from ...);

在单行子查询中,子查询的结果是单行数据,所以能进行=。如果是多行查询,那么此时就不能进行判等,而是使用inallany这三个关键字,来进行范围判断。

in:判断是否是多行数据中的一个

in关键字:查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10
己的
select ename,job,sal,deptno from emp where job in (select job from emp where deptno=10) and deptno!=10;

all:判断是否所有数据都满足条件
all关键字:显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号
select ename,job,sal,deptno from emp where sal > all (select sal from emp where deptno=30);

any:判断是否有数据满足条件
any关键字:显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门
的员工)
select ename,job,sal,deptno from emp where sal > any (select sal from emp where deptno=30);

多列子查询

单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询则是指查询返回多个列数据的子查询语句。
select ... from ...
where (列1, 列2...) 逻辑运算符 (select 列1, 列2... from ...);

查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人

select ename from emp where (deptno,job)=(select deptno,job from emp where ename='smith') and ename!='smith';

from子句中使用子查询

子查询语句出现在 from 子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。
select ... from (select ... from ...) as 别名 where ...;
1.显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资
select ename,deptno,sal,format(asal,2) from emp,(select deptno de,avg(sal) asal from emp group by deptno) tmp where sal>asal and deptno=de;

2.查找每个部门工资最高的人的姓名、工资、部门、最高工资
select ename,sal,emp.deptno from emp,(select deptno,max(sal) msal from emp group by deptno) tmp where sal=msal and emp.deptno=tmp.deptno;

3.显示每个部门的信息(部门名,编号,地址)和人员数量

合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 unionunion all。

union

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。

select ... from ... union select ... from ...;
将工资大于 2500 或职位是 MANAGER 的人找出来
select ename,sal,job from emp where sal>2500 union select ename,sal,job from emp where job='manager';

union all

该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。
select ... from ... union all select ... from ...;

将工资大于2500或职位是MANAGER的人找出来

select ename,sal,job from emp where sal>2500 union all select ename,sal,job from emp where job='manager';

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

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

相关文章

数据集-目标检测系列- 海边漫步锻炼人检测数据集 person >> DataBall

数据集-目标检测系列- 海边漫步锻炼人检测数据集 person >> DataBall DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球…

【汇编语言】call 和 ret 指令(三) —— 深度解析汇编语言中的批量数据传递与寄存器冲突

文章目录 前言1. 批量数据的传递1.1 存在的问题1.2 如何解决这个问题1.3 示例演示1.3.1 问题说明1.3.2 程序实现 2. 寄存器冲突问题的引入2.1 问题引入2.2 分析与解决问题2.2.1 字符串定义方式2.2.2 分析子程序功能2.2.3 得到子程序代码 2.3 子程序的应用2.3.1 示例12.3.2 示例…

刷题日常(找到字符串中所有字母异位词,​ 和为 K 的子数组​,​ 滑动窗口最大值​,全排列)

找到字符串中所有字母异位词 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 题目分析: 1.将p里面的字符先丢进一个hash1中,只需要在S字符里面找到多少个和他相同的has…

Git 快速入门:全面了解与安装步骤

Git 快速入门:全面了解与安装步骤 一、关于Git 1.1 简介 Git 是一个开源的分布式版本控制系统,由 Linus Torvalds 于 2005 年创建,最初是为了更好地管理 Linux 内核开发而设计。 Git用于跟踪计算机文件的变化,特别是源代码文件…

私有库gitea安装

一 gitea是什么 Gitea是一款自助Git服务,简单来说,就是可以一个私有的github。 搭建很容易。 Gitea依赖于Git。 类似Gitea的还有GitHub、Gitee、GitLab等。 以下是安装步骤。 二 安装sqilite 参考: 在windows上安装sqlite 三 安装git…

[CTF/网络安全] 攻防世界 upload1 解题详析

[CTF/网络安全] 攻防世界 upload1 解题详析 考察文件上传&#xff0c;具体原理及姿势不再赘述。 姿势 在txt中写入一句话木马<?php eval($_POST[qiu]);?> 回显如下&#xff1a; 查看源代码&#xff1a; Array.prototype.contains function (obj) { var i this.…

基于HTML+CSS的房地产销售网站设计与实现

摘 要 房地产销售系统&#xff0c;在二十年来互联网时代下有着巨大的意义&#xff0c;随着互联网不断的发展扩大&#xff0c;一个方便直 观的房地产管理系统的网站开发是多么地有意义&#xff0c;不仅打破了传统的线下看房&#xff0c;线下获取资讯&#xff0c;也给房地产从业…

说说Elasticsearch拼写纠错是如何实现的?

大家好&#xff0c;我是锋哥。今天分享关于【说说Elasticsearch拼写纠错是如何实现的&#xff1f;】面试题。希望对大家有帮助&#xff1b; 说说Elasticsearch拼写纠错是如何实现的&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中&…

如何把产品3D模型放到网站上进行3D展示或3D互动?

要将产品3D模型放到网站上进行3D展示或3D互动&#xff0c;可以按照以下步骤进行&#xff1a; 一、准备3D模型 使用3D建模软件&#xff08;如3ds Max、Maya、Blender、C4D等&#xff09;制作好产品的3D模型。 确保3D模型的格式是网站或平台所支持的&#xff0c;常见的格式包括…

SpringBoot集成Flowable

一、工作流介绍 1、概念 通过计算机对业务流程的自动化管理。工作流是建立在业务流程的基础上&#xff0c;一个软件的系统核心根本上还是系统的业务流程&#xff0c;工作流只是协助进行业务流程管理。 解决的是&#xff1a;在多个参与者之间按照某种预定义的规则自动进行传递文…

1-1 Gerrit实用指南

注&#xff1a;学习gerrit需要拥有git相关知识&#xff0c;如果没有学习过git请先回顾git相关知识点 黑马程序员git教程 一小时学会git git参考博客 git 实操博客 1.0 定义 Gerrit 是一个基于 Web 的代码审查系统&#xff0c;它使用 Git 作为底层版本控制系统。Gerrit 的主要功…

鸿蒙开发:自定义一个任意位置弹出的Dialog

前言 鸿蒙开发中&#xff0c;一直有个问题困扰着自己&#xff0c;想必也困扰着大多数开发者&#xff0c;那就是&#xff0c;系统提供的dialog自定义弹窗&#xff0c;无法实现在任意位置进行弹出&#xff0c;仅限于CustomDialog和Component struct的成员变量&#xff0c;这就导致…

Matlab模块From Workspace使用数据类型说明

Matlab原文连接&#xff1a;Load Data Using the From Workspace Block 模型&#xff1a; 从信号来源的数据&#xff1a; timeseries 数据&#xff1a; sampleTime 0.01; numSteps 1001;time sampleTime*[0:(numSteps-1)]; time time;data sin(2*pi/3*time);simin time…

架构01-演进中的架构

零、文章目录 架构01-演进中的架构 1、原始分布式时代&#xff1a;Unix设计哲学下的服务探索 &#xff08;1&#xff09;背景 时间&#xff1a;20世纪70年代末到80年代初计算机硬件&#xff1a;16位寻址能力、不足5MHz时钟频率的处理器、128KB左右的内存转型&#xff1a;从…

社群赋能电商:小程序 AI 智能名片与 S2B2C 商城系统的整合与突破

摘要&#xff1a;本文聚焦于社群在电商领域日益凸显的关键地位&#xff0c;深入探讨在社群粉丝经济迅猛发展背景下&#xff0c;小程序 AI 智能名片与 S2B2C 商城系统如何与社群深度融合&#xff0c;助力电商突破传统运营局限&#xff0c;挖掘新增长点。通过分析社群对电商的价值…

【electron-vite】搭建electron+vue3框架基础

一、拉取项目 electron-vite 中文文档地址&#xff1a; https://cn-evite.netlify.app/guide/ 官网网址&#xff1a;https://evite.netlify.app/ 版本 vue版本&#xff1a;vue3 构建工具&#xff1a;vite 框架类型&#xff1a;Electron JS语法&#xff1a;TypeScript &…

EasyDarwin搭建直播推流服务

学习链接 easydarwin官网 - 这里看介绍 easydarwin软件下载地址 - 百度网盘 easydarwin视频 B站 文章目录 学习链接使用下载EasyDarwin压缩包&#xff0c;并解压到目录启动EasyDarwin点播直播easyplayer.jsapidocffmpeg推流rtsp & ffplay拉流 使用 下载EasyDarwin压缩包…

【RISC-V CPU debug 专栏 2 -- Debug Module (DM), non-ISA】

文章目录 调试模块(DM)功能必须支持的功能可选支持的功能兼容性要求规模限制Debug Module Interface (DMI)总线类型地址与操作地址空间控制机制Debug Module Interface Signals请求信号响应信号信号流程Reset Control复位控制方法全局复位 (`ndmreset`)Hart 复位 (`hartreset…

【WRF后处理】WRF模拟效果评价及可视化:MB、RMSE、IOA、R

【WRF后处理】模拟效果评价及可视化 准备工作模型评价指标Python实现代码Python处理代码:导入站点及WRF模拟结果可视化图形及评价指标参考在气象和环境建模中(如使用 WRF 模型进行模拟),模型性能评价指标是用于定量评估模拟值与观测值之间偏差和拟合程度的重要工具。 本博客…

基于JSP+MySQL的网上招聘系统的设计与实现

摘要 在这样一个经济飞速发展的时代&#xff0c;人们的生存与生活问题已成为当代社会需要关注的一个焦点。对于一个刚刚 踏入社会的年轻人来说&#xff0c;他对就业市场和形势了解的不够详细&#xff0c;同时对自己的职业规划也很模糊&#xff0c;这就导致大量的 时间被花费在…