当前位置: 首页 > news >正文

26.多表查询

1.笛卡尔集

创建俩表:

-- 创建部门表(dept)
use mysql_learn
CREATE TABLE dept (deptno INT PRIMARY KEY,       dname VARCHAR(50) NOT NULL,   loc VARCHAR(50)      
);-- 创建员工表(emp)
CREATE TABLE emp (empno INT PRIMARY KEY,        ename VARCHAR(50) NOT NULL,  job VARCHAR(50),             mgr INT,                       hiredate DATE,                sal DECIMAL(10,2) NOT NULL,   comm DECIMAL(10,2),           deptno INT
);

插入一些示例数据:

-- 向部门表插入数据
INSERT INTO dept (deptno, dname, loc) VALUES
(10, 'ACCOUNTING', 'NEW YORK'),
(20, 'RESEARCH', 'DALLAS'),
(30, 'SALES', 'CHICAGO'),
(40, 'OPERATIONS', 'BOSTON');-- 向员工表插入数据
INSERT INTO emp (empno, ename, job, mgr, hiredate, sal, comm, deptno) VALUES
(7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800.00, NULL, 20),
(7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600.00, 300.00, 30),
(7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250.00, 500.00, 30),
(7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975.00, NULL, 20),
(7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250.00, 1400.00, 30),
(7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850.00, NULL, 30),
(7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450.00, NULL, 10),
(7788, 'SCOTT', 'ANALYST', 7566, '1982-12-09', 3000.00, NULL, 20),
(7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000.00, NULL, 10),
(7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500.00, 0.00, 30),
(7876, 'ADAMS', 'CLERK', 7788, '1983-01-12', 1100.00, NULL, 20),
(7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950.00, NULL, 30),
(7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000.00, NULL, 20),
(7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300.00, NULL, 10);  

看看结果:

部门表,里面有4条记录

雇员表,里面有14条记录

假设现在有个需求:打印某个员工的工资条。

我们有两张表:1️⃣雇员表,2️⃣部门表。

当我们根据前面所学习的知识直接对两个表同时查询时会出现以下情况:

SELECT * from dept,emp

可以看到,我们直接将俩表连起来一起查出来的记录有56条之多。

仔细探查我们会发现,这些结果实际上就是第一个表中的四条记录和第二张表的一条记录进行拼接而成的。也就是4*14=56条记录。这就是笛卡尔集

所以这些直接进行查询获得的信息是有冗余的信息,为了得到真正有意义的信息,我们需要做的就是过滤

2.笛卡尔集的解决

为了过滤出有意义的信息,我们直接在where子句中做即可。

SELECT * from dept,empwhere dept.deptno = emp.deptno

这样我们就解决了笛卡尔集,得到了真正有意义的14条记录。

对sql语句稍作修改,也就可以得到每个员工的工资条了。

SELECT ename as '姓名',job as '工作',sal as '薪水',dname as '部门',deptno as '部门号'from dept,empwhere dept.deptno = emp.deptno

我们会发现这样会报错。

SQL 错误 [1052] [23000]: Column 'deptno' in field list is ambiguous

因为我们进行的是多表查询,deptno这个字段在俩表中同时存在,直接写会有歧义的。

我们对sql再次进行修改:

SELECT ename as '姓名',job as '工作',sal as '薪水',dname as '部门',emp.deptno as '部门号'from dept,empwhere dept.deptno = emp.deptno

得到了我们想要的结果了。

注意:多表查询的条件不能少于表的个数减一,否则就会出现笛卡尔集

3.练习

再创建一个工资等级表。

CREATE TABLE grade_salary (grade INT,losal DECIMAL(10, 2),hisal DECIMAL(10, 2)
);INSERT INTO grade_salary (grade, losal, hisal)
VALUES 
(1, 1000.00, 1200.00),
(2, 1201.00, 2000.00),
(3, 2001.00, 3000.00),
(4, 3001.00, 9999.00),
(5, 3001.00, 9999.00);

(1)显示各个员工的姓名,工资,工资等级

SELECT ename,sal,gradefrom emp,grade_salary

很显然,直接查俩个表会出现笛卡尔集。

我们做一下过滤:可以直观的分析出雇员表emp和工资级别表grade_salary之间的联系就是员工工资在工资级别表中的那一个级别区间,也即员工工资和工资级别区间相对应的记录就是我们要查询的结果。

基于此,可以使用between and 语句来判断。

SELECT ename,sal,gradefrom emp,grade_salary gswhere sal between losal and hisal;

(2)显示员工名字,工资,所在部门名字,并按部门号降序排列

显然我们这次需要查询,emp和dept这两张表,为了防止出现笛卡尔集,做一下过滤,最后用order by做一下排序。

SELECT ename,sal,dnamefrom emp e,dept dwhere e.deptno = d.deptnoorder by d.deptno DESC ;

再看一眼,按部门号降序排序也做好了。

http://www.lryc.cn/news/572014.html

相关文章:

  • Vue 二维码组件
  • 02-three.js Transform objects
  • 什么是Gateway
  • 详细讲解Redis为什么被设计成单线程
  • 稀疏大模型架构与训练算法研究
  • 最新期刊影响因子,基本包含全部期刊
  • vue | vue 插件化机制,全局注册 和 局部注册
  • 基于python的web系统界面登录
  • 深入理解mysql索引
  • PHP vs Python (Flask/Django) vs Java (SpringBoot) vs Vue:2024全栈技术终极对决
  • singlefligt使用方法和源码解读
  • MySQL 索引和select优化
  • ​​网络工程师知识点精讲与例题解析:数据链路层技术​​
  • 计算机视觉课程总结
  • 【Node.js 的底层实现机制】从事件驱动到异步 I/O
  • Python Peewee库连接和操作MySQL数据库
  • 条件向量运算与三元表达式
  • C语言——枚举
  • 解决Matplotlib三维图无法旋转的问题
  • AndroidR平台ToastPresenter引出BinderProxy泄漏
  • 实战指南:用DataHub管理Hive元数据
  • SkyWalking 部署与应用(Windows)
  • 7-4 身份证号处理
  • 企业班车出行服务系统的SDK选型、核心功能优化迭代的避坑复盘
  • Android软件适配遥控器需求-案例经验分享
  • WebRTC(六):ICE协议
  • 汇编语言期末快速过手笔记
  • React Native WebView键盘难题:如何让输入框不被键盘遮挡?
  • Alpha WORLD上线在即:首发AIOT,重塑项目价值格局
  • 48-Oracle CDB下的SID-实例名-服务名