MySQL复合查询

MySQL复合查询

  • 在之前我们对MySQL的表的查询都是对一张表进行查询操作,但这在实际的开发中是远远不够的。

多表查询

依然使用的是上一次的脚本语言,这里再贴出来一份

sql 复制代码
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);
  • 实际开发中往往数据来自于不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张 表EMP,DEPT,SALGRADE来演示如何进行多表查询
  1. 显示雇员名、雇员工资以及所在部门的名字因为上面的数据来自EMP和DEPT表,因此要联合查询

​ 这里可以看到,如果只是简单的选择两张表,那最终的结果就是两张表的排列组合,这里称为笛卡尔集。

eg:

  • 显示部门号为10的部门名,员工名和工资
sql 复制代码
select ename, sal,dname from EMP, DEPT where EMP.deptno=DEPT.deptno and 
DEPT.deptno = 10;

自连接

自连接就是指在同一张表进行查询,将自己的表进行两次重命名,最后得到一个由两个相同的表组成的大表。

  • 显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号--empno)
sql 复制代码
-- 使用到表的别名

from emp leader, emp worker,给自己的表起别名,因为要先做笛卡尔积,所以别名可以先识别

select leader.empno,leader.ename from emp leader, emp worker where 
leader.empno = worker.mgr and worker.ename='FORD';

子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

单行子查询

  • 显示SMITH同一部门的员工
sql 复制代码
select * from EMP WHERE deptno = (select deptno from EMP where ename='smith');

多行子查询

  • in关键字;查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的
sql 复制代码
select ename,job,sal,deptno from emp where job in (select distinct job from  emp where deptno=10) and deptno<>10;
  • all关键字;显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号
sql 复制代码
select ename, sal, deptno from EMP where sal > all(select sal from EMP where  deptno=30);
  • any关键字;显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门 的员工)
sql 复制代码
select ename, sal, deptno from EMP where sal > any(select sal from EMP where  deptno=30);

8.4.3 多列子查询

单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言 的,而多列子查询则是指查询返回多个列数据的子查询语句

  • 案例:查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人
sql 复制代码
mysql> select ename from EMP where (deptno, job)=(select deptno, job from EMP where ename='SMITH') and ename <> 'SMITH';

再from中使用子查询

  • 子查询语句出现在from子句中,这里要用到数据查询的技巧,把一个子查询当作一个临时表来使用

  • 显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资

sql 复制代码
select ename, deptno, sal, format(asal,2) from EMP, (select avg(sal) asal, deptno dt from EMP group by deptno) tmp where EMP.sal > tmp.asal and EMP.deptno=tmp.dt;
相关推荐
遇事不決洛必達21 分钟前
【数据库系列】本地映射云服务器Mysql的方法
服务器·数据库·mysql·定时任务
海鸥-w32 分钟前
用python (fastapi)做项目第一天创建项目结构,数据建表,ORM配置安装,写第一个接口
数据库·python·fastapi
zfoo-framework1 小时前
通过redis-cli+lua脚本查询redis数据
数据库·redis·lua
牛栓柱1 小时前
【后端实战】用 Supabase + React/TS 零成本构建高并发 Multi-Agent 服务
前端·数据库·人工智能·后端·react.js·前端框架
yuezhilangniao1 小时前
xtr备份prepare到底变化了啥
mysql
yyk的萌1 小时前
创建属于自己的mysql的mcp
mysql·adb·ai·mcp
流烟默1 小时前
腾讯云Centos7.6使用yum安装MySQL8
mysql·centos·腾讯云
仙俊红1 小时前
如何优化 MySQL 深分页 SQL
android·sql·mysql
yyuuuzz2 小时前
谷歌云基础服务的入门认知
linux·运维·服务器·数据库·人工智能·github
超梦dasgg2 小时前
工作中 MySQL 读写分离主从延迟:成因、影响、落地方案、生产实战处理
数据库·mysql