MySQL (五)------多表查询练习

news2024/12/23 18:12:18

我们在开发中,根据不同的业务需求往往需要通过2张及以上的表中去查询需要的数据。所以我们有必要学习2张及以上的表的查询。其实不管是几张表的查询,都是有规律可循的。

1.1 准备数据

-- 部门表
CREATE TABLE dept (
  id INT PRIMARY KEY PRIMARY KEY, -- 部门id
  dname VARCHAR(50), -- 部门名称
  loc VARCHAR(50) -- 部门位置
);

-- 添加4个部门
INSERT INTO dept(id,dname,loc) VALUES 
(10,'教研部','北京'),
(20,'学工部','上海'),
(30,'销售部','广州'),
(40,'财务部','深圳');

-- 职务表,职务名称,职务描述
CREATE TABLE job (
  id INT PRIMARY KEY,
  jname VARCHAR(20),
  description VARCHAR(50)
);

-- 添加4个职务
INSERT INTO job (id, jname, description) VALUES
(1, '董事长', '管理整个公司,接单'),
(2, '经理', '管理部门员工'),
(3, '销售员', '向客人推销产品'),
(4, '文员', '使用办公软件');

-- 员工表
CREATE TABLE emp (
  id INT PRIMARY KEY, -- 员工id
  ename VARCHAR(50), -- 员工姓名
  job_id INT, -- 职务id
  mgr INT , -- 上级领导
  joindate DATE, -- 入职日期
  salary DECIMAL(7,2), -- 工资
  bonus DECIMAL(7,2), -- 奖金
  dept_id INT, -- 所在部门编号
  CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
  CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
);

-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);

-- 工资等级表
CREATE TABLE salarygrade (
  grade INT PRIMARY KEY,
  losalary INT,
  hisalary INT
);

-- 添加5个工资等级
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);

1.2 练习

1.2.1 练习1

查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述

具体操作: 1.确定要查询哪些表:emp e, job j

SELECT * FROM emp e INNER JOIN job j;

  2.确定表连接条件: e.job_id=j.id

SELECT * FROM emp e INNER JOIN job j ON e.job_id=j.id;

  3.确定查询字段:员工编号,员工姓名,工资,职务名称,职务描述

显示内连接查询

SELECT e.`id`, e.`ename`, e.`salary`, j.`jname`, j.`description` 
FROM emp e 
INNER JOIN job j ON e.job_id=j.id;

也可以: 隐式内连接查询

SELECT e.id,e.ename,e.salary,j.jname,j.description 
FROM emp e,job j 
WHERE e.job_id=j.id

1.2.2 练习2

查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置

具体操作: 1. 确定要查询哪些表,emp e, job j, dept d

SELECT * FROM emp e INNER JOIN job j INNER JOIN dept d;

   2. 确定表连接条件 e.job_id=j.id and e.dept_id=d.id

SELECT * 
FROM emp e 
INNER JOIN job j 
INNER JOIN dept d 
ON e.job_id=j.id AND e.dept_id=d.id;

   3. 确定查询字段:员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置

SELECT e.`id`, e.`ename`, e.`salary`, j.`jname`, j.`description`, d.`dname`, d.`loc` 
FROM emp e 
INNER JOIN job j 
INNER JOIN dept d 
ON e.job_id=j.id AND e.dept_id=d.id;
SELECT e.`id`, e.`ename`, e.`salary`, j.`jname`, j.`description`, d.`dname`, d.`loc` 
FROM emp e,job j ,dept d 
WHERE e.job_id=j.id AND e.dept_id=d.id;

1.2.3 练习3

查询所有员工信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级

具体操作: 1. 确定要查询哪些表,emp e, job j, dept d, salarygrade s

SELECT * FROM emp e INNER JOIN job j INNER JOIN dept d INNER JOIN salarygrade s;

   2. 确定表连接条件 e.job_id=j.id and e.dept_id=d.id and e.salary between s.losalary and hisalary

SELECT * 
FROM emp e 
INNER JOIN job j 
INNER JOIN dept d 
INNER JOIN salarygrade s 
ON e.job_id=j.id AND e.dept_id=d.id AND e.salary 
BETWEEN s.losalary AND s.hisalary;

   3. 确定查询字段:员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级

SELECT e.`ename`, e.`salary`, j.`jname`, j.`description`, d.`dname`, d.`loc`, s.`grade` 
FROM emp e 
INNER JOIN job j 
INNER JOIN dept d 
INNER JOIN salarygrade s 
ON e.job_id=j.id AND e.dept_id=d.id AND e.salary 
BETWEEN s.losalary AND hisalary;
SELECT e.`ename`, e.`salary`, j.`jname`, j.`description`, d.`dname`, d.`loc`, s.`grade` 
FROM emp e ,job j ,dept d ,salarygrade s 
WHERE e.job_id=j.id AND e.dept_id=d.id AND e.salary 
BETWEEN s.losalary AND hisalary;

1.2.3.1 多表查询规律总结

  1. 不管我们查询几张表,表连接查询会产出笛卡尔积,我们需要消除笛卡尔积,拿到正确的数据。我们需要找到表与表之间通过哪个字段关联起来的(通常是外键=主键

  2. 消除笛卡尔积规律:2张表需要1个条件,3张表需要2个条件,4张表需要3个条件。(条件数量=表的数量-1),每张表都要参与进来

  3. 多表连接查询步骤: 3.1. 确定要查询哪些表  3.2. 确定表连接条件 3.3. 确定查询字段

1.2.4 练习4

查询经理的信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级

具体操作: 1. 确定要查询哪些表,emp e, job j, dept d, salarygrade s

  SELECT * FROM emp e INNER JOIN job j INNER JOIN dept d INNER JOIN salarygrade s;

   2. 确定表连接条件 e.job_id=j.id and e.dept_id=d.id and e.salary between s.losalary and hisalary

SELECT * 
FROM emp e 
INNER JOIN job j 
INNER JOIN dept d 
INNER JOIN salarygrade s 
ON e.job_id=j.id AND e.dept_id=d.id AND e.salary 
BETWEEN s.losalary AND hisalary;

  额外条件:只需要查询经理的信息(j.jname='经理')

  3. 确定查询字段:员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
SELECT e.`ename`, e.`salary`, j.`jname`, j.`description`, d.`dname`, d.`loc`, s.`grade` 
FROM emp e 
INNER JOIN job j 
INNER JOIN dept d 
INNER JOIN salarygrade s 
ON e.job_id=j.id AND e.dept_id=d.id AND e.salary 
BETWEEN s.losalary AND hisalary AND j.jname='经理';
SELECT e.`ename`, e.`salary`, j.`jname`, j.`description`, d.`dname`, d.`loc`, s.`grade` 
FROM emp e ,job j ,dept d ,salarygrade s 
WHERE e.job_id=j.id 
AND e.dept_id=d.id 
AND e.salary 
BETWEEN s.losalary AND hisalary
AND j.jname="经理";

1.2.5 练习5

查询出部门编号、部门名称、部门位置、部门人数

具体操作:

  1. 去员工表中找到每个部门的人数和部门id
SELECT dept_id, COUNT(*) FROM emp GROUP BY dept_id;

  2. 再和部门表连接查询
SELECT * 
FROM dept d 
INNER JOIN 
(SELECT dept_id, COUNT(*) FROM emp GROUP BY dept_id) e ON e.dept_id=d.`id`;

 

  3. 显示对应的字段
SELECT d.`id`, d.dname, d.`loc`, e.total 部门人数 
FROM dept d 
INNER JOIN 
(SELECT dept_id, COUNT(*) total FROM emp GROUP BY dept_id) e 
ON e.dept_id=d.`id`;
SELECT d.*, IFNULL(e.total,0) '部门人数'
FROM dept d 
LEFT JOIN 
(SELECT dept_id, COUNT(id) 'total' FROM emp GROUP BY dept_id) e 
ON e.dept_id=d.`id`;

​​​​​​​

 

1.2.6 练习6

查询所有员工信息。显示员工信息和部门名称,没有员工的部门也要显示

具体操作: 1. 确定要查询哪些表,emp e, dept d

SELECT * FROM emp e INNER JOIN dept d;

 

  2. 确定表连接条件 e.dept_id=d.id,没有员工的部门也要显示。右边数据要全部显示所以使用右外连接
SELECT * FROM emp e RIGHT JOIN dept d ON e.dept_id=d.id;

 

  注意:没有员工的部门也要显示。右边数据要全部显示所以使用右外连接

  3. 确定查询字段:员工信息,部门名称
SELECT e.*, d.`dname` 
FROM emp e 
RIGHT JOIN dept d ON e.dept_id=d.id;

1.2.7 练习7

查询所有员工信息。显示员工姓名,员工工资,职务名称,工资等级,并按工资升序排序

具体操作: 1. 确定要查询哪些表,emp e, job j, salarygrade s

​​​​​​​
SELECT * 
FROM emp e 
INNER JOIN job j INNER JOIN salarygrade s;

   2. 确定表连接条件 e.job_id=j.id and e.salary between s.losalary and s.hisalary

SELECT * 
FROM emp e 
INNER JOIN job j 
INNER JOIN salarygrade s 
ON e.job_id=j.id AND e.salary 
BETWEEN s.losalary AND s.hisalary;

   3. 确定查询字段:员工姓名,员工工资,工资等级,并按工资升序排序

SELECT e.`ename`, j.`jname`, e.`salary`, s.`grade` 
FROM emp e 
INNER JOIN job j 
INNER JOIN salarygrade s 
ON e.job_id=j.id AND e.salary 
BETWEEN s.losalary AND s.hisalary ORDER BY e.`salary`;

1.2.8 练习8

列出所有员工的姓名及其直接上级的姓名,没有领导的员工也需要显示

具体操作:

​​​​​​​

  1. 确定要查询哪些表,emp e, emp m

SELECT * FROM emp e INNER JOIN emp m;

   2. 确定表连接条件 e.mgr=e2.id

SELECT * FROM emp e INNER JOIN emp m ON e.`mgr`=m.`id`;
SELECT * FROM emp e LEFT JOIN emp m ON e.`mgr`=m.`id`;

  **我们发现少了一条数据,因为罗贯中是董事长没有上司**
  没有领导的员工也需要显示,所以左表的数据需要全部显示。使用左外连接

  3. 确定查询字段:员工的姓名及其直接上级的姓名

SELECT e.`ename`, IFNULL(m.`ename`, '没有') 上司 
FROM emp e LEFT JOIN emp m ON e.`mgr`=m.`id`;

1.2.9 练习9

查询入职期早于直接上级的所有员工编号、姓名、部门名称

具体操作: 1. 确定要查询哪些表,emp e, emp m, dept d

SELECT * FROM emp e INNER JOIN emp m INNER JOIN dept d;

   2. 确定表连接条件 e.mgr=m.id and e.dept_id=d.id and e.dept_id=d.id and e.joindate<m.joindate

SELECT * 
FROM emp e 
INNER JOIN emp m 
INNER JOIN dept d 
ON e.mgr=m.id AND e.dept_id=d.id AND e.joindate<m.joindate;

   3. 确定查询字段:员工编号、姓名、部门名称

SELECT e.`id`, e.`ename`, d.`dname` 
FROM emp e 
INNER JOIN emp m 
INNER JOIN dept d 
ON e.mgr=m.id AND e.joindate<m.joindate AND e.`dept_id`=d.`id`;

1.2.10 练习10

查询工资高于公司平均工资的所有员工信息。显示员工信息,部门名称,上级领导,工资等级

具体操作: 先统计公司平均工资

SELECT AVG(salary) FROM emp;

  1. 确定要查询哪些表,emp e, emp m, dept d, salarygrade s

SELECT * 
FROM emp e 
INNER JOIN emp m 
INNER JOIN dept d 
INNER JOIN salarygrade s;
  2. 确定表连接条件 e.dept_id=d.id and e.mgr=m.id and e.salary between s.losalary and hisalary and e.salary>公司平均薪金
SELECT * 
FROM emp e 
INNER JOIN emp m 
INNER JOIN dept d 
INNER JOIN salarygrade s 
WHERE e.dept_id=d.id AND e.mgr=m.id AND e.salary 
BETWEEN s.losalary AND hisalary AND e.salary>(SELECT AVG(salary) FROM emp);

 3. 确定查询字段:员工信息,部门名称,上级领导,工资等级。 

SELECT e.*, d.`dname`, m.`ename`, s.`grade` 
FROM emp e 
INNER JOIN emp m 
INNER JOIN dept d 
INNER JOIN salarygrade s 
WHERE e.dept_id=d.id AND e.mgr=m.id AND e.salary 
BETWEEN s.losalary AND hisalary AND e.salary>(SELECT AVG(salary) FROM emp);

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

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

相关文章

Databend 开源周报 第 75 期

Databend 是一款强大的云数仓。专为弹性和高效设计。自由且开源。即刻体验云服务&#xff1a;https://app.databend.com 。 What’s New 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 Features & Improvements ✨ Format 实现 JSON 输出格式 …

C++模板进阶(非类型模板参数 + 模板特化)

我们另一篇模板初阶介绍链接&#xff1a;http://t.csdn.cn/Ox8Dm 目录 一、非类型模板参数 1.1 非类型模板参数概念 1.2 模板类型的静态数组 二、模板特化 2.1 函数模板特化 2.2 类模板特化 2.2.1 类模板全特化 2.2.2 类模板半特化&#xff08;偏特化&#xff09; 2.2.…

Facebook运营主页需要注意的几个问题

Facebook运营主页需要注意的几个问题主页的权重和流量都是决定流量的关键因素&#xff0c;也就是我们常说的引流&#xff0c;而流量又是需要转化的&#xff0c;因为只有用户认可你&#xff0c;才会有更多的点击、收藏、分享和主页的链接。在社交媒体时代要想更好地推广品牌产品…

openssl 编译动态库 win11 vs2022

官网 openssl官网 安装perl activestate_perl_官网 需要下载cli_installer 下载后双击下载好的exe 一般就是下面这个执行文件 state-remote-installer.exe 需要按照提示在powershell中执行网页提示的命令。 安装nasm nasm官网 以管理员方式运行安装 并加入环境变量中…

《MySQL高级篇》十、数据库其他调优策略

文章目录1.数据库调优的措施1.1调优的目标1.2 如何定位调优问题1.3 调优的维度和步骤第1步&#xff1a;选择适合的DBMS第2步:优化表设计第3步:优化逻辑查询第4步:优化物理查询第5步:使用Redis或 Memcached 作为缓存第6步&#xff1a;库级优化2. 优化MySQL服务器2.1 优化服务器硬…

定时任务、cron表达式、springBoot整合定时任务和异步任务-59

一&#xff1a;定时任务 1.1 官网地址 http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html 1.2 cron表达式 Cron表达式是一个字符串&#xff0c;字符串以5或6个空格隔开&#xff0c;分为6或7个域&#xff0c;每一个域代表一个含义&am…

【Nacos】一文为你揭露它的强大

注&#xff1a;为什么要使用nacos作为注册中心呢&#xff1f;这样的好处在哪呢&#xff1f;一、 什么是nacosNacos 是 Dynamic Naming and Configuration Service 的首字母简称&#xff1b;一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助您…

java 方法看这一篇文章就够了

第一章 方法概念 1实现特定功能的一段代码,可反复被调用计算机 — 模拟现实 — 通过软件控制硬件 比如豆浆机 — 里面的微控制器 — 控制豆浆机 右图面板上有很多种模式 每一种模式对应不同的搅拌次数、搅拌时间、烧水温度等… 这些硬件的动作都需要软件的控制 硬件的每一种模式…

el-table使用sortablejs实现行、列拖拽

效果图 代码如下 <script src"//unpkg.com/sortablejs1.7.0/Sortable.js"></script> <script src"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <link rel"stylesheet" href"//unpkg.com/eleme…

文件或目录损坏且无法读取?正确恢复文件的4个方法

你有没有遇到过“文件损坏已无法读取”的提示窗口&#xff1f;相信使用电脑的你&#xff0c;或多或少都会遇到过&#xff0c;尤其是我们使用硬盘或者移动硬盘的时候。 遇到这种问题&#xff0c;我们第一时间不是按照系统提示去删除或者格式化&#xff0c;而是要寻找合适的方法…

DES算法笔记

文章目录DES简介FeistelDES算法流程EncipheringKey ScheduleDecipheringThe Cipher Function f(R, K)Triple DES算法OpenSSL接口S-box实现参考资料DES简介 发布文档&#xff1a;FIPS 46-3, 1977 block size: 8 bytes.Key Size: 8 bytes 64 bits, 原本设计每隔7 bits保留一个…

关于string boot项目实训课(准备工作)

一、页面–web页面–java代码之间的逻辑关系 首先在java文件夹下创建一个java类 Controller//类上面要加入注解 public class TestController {GetMapping("login")//对应web请求--localhost:9991/Login//类方法&#xff0c;用于处理逻辑public String login(Strin…

实时Windows AD用户帐户锁定分析器工具

实时帐户锁定工具提供有关域帐户锁定原因的实时报表。本机Windows Active Directory帐户锁定策略是阻止连续、时限性、寻求登录的密码猜测尝试的一种实用方法&#xff0c;这会由于使用错误的密码而导致帐户锁定。帐户锁定的其他原因可能包括&#xff1a;由于采用严格的密码设置…

【项目】 改造原前端ViewUI框架,使其支持ElementUI 与 Avue

一、背景说明 因为原来前端的同事习惯用&#xff0c;ViewUI框架&#xff0c;于是基线版本的项目&#xff0c;都是使用的ViewUI框架搭建的。 但是&#xff0c;这个ViewUI的表格&#xff0c;是引用的第三方的vux的框架&#xff0c;在网上很少人使用&#xff0c;所以遇到问题&…

如果为产业互联网时代的发展寻找一个注脚的话,新产业无疑是一个最主要的特征

如果为产业互联网时代的发展寻找一个注脚的话&#xff0c;新产业无疑是一个最主要的特征。在这个时代&#xff0c;诸多原本看似无法改变的产业有了改变的可能性&#xff0c;诸多看似无法破解的痛点和难题有了新的解决方案。如果一定要找到导致这一蜕变的根本原因的话&#xff0…

用户积分和积分排行榜功能微服务实现

文章目录需求分析什么是积分积分的获取为啥需要积分服务数据库表创建 ms-points 积分微服务新增用户积分功能用户积分实体积分控制层积分业务逻辑层数据交互mapper层网关 ms-gateway 服务添加积分微服务路由用户服务中添加用户积分逻辑项目测试积分排行榜TopN(关系型数据库)构造…

記錄centos8 升級Python3.6到Python3.9以及可能遇到的問題

目录下载Python3.9.9可能出現的問題及解決方案安裝python3.9可能出現的問題及解決方案建立Python3和pip3的软鏈接:查看Python3和Pip3是否正确的被安装&#xff1a;将/usr/local/python3/bin加入PATHCentos8-默认的Python、python2版本为2.7&#xff0c;python3版本為3.6&#x…

迭代器深入理解

目录 vector 例子引入 迭代器的价值 通过vector和list 迭代器的差异再次深入理解 vector 例子引入 在学习vector底层erase&#xff0c;碰到迭代器失效的时候我有个疑惑&#xff0c;为什么sgi 版&#xff08;Linux g使用的&#xff09;库里实现的迭代器对于有些迭代器失效情…

threejs教程(一)

插件安装 npm i three项目引入 这里我随便找的VUE项目练习的 import * as THREE from "three";大致介绍一下threejs的逻辑 一般我们用它是来搭建三维模型的,搭建三维模型就需要的三个要素 场景(scene) 渲染器(renderer) 和相机(camera) 场景简单理解就是唱戏的戏台…

【C++升级之路】第六篇:模板初阶(函数模板类模板)

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【C学习与应用】 ✒️✒️本篇内容&#xff1a;泛型编程的概念&#xff0c;函数模板的概念、格式、原理和基础使用方法&#xff0c;类模板的格式和基础使用…