MySQL 多表操作和查询公式

下面是代码:

可以保存随意更改使用:

 #多表操作

-- 方式一

#创建外键约束
CREATE database mydb3;
use mydb3;
-- 创建一个部门表 主表
CREATE TABLE IF not EXISTS dept(
	detpno VARCHAR(20) PRIMARY KEY,
	NAME VARCHAR(20) -- 部门名字
	);  
-- 创建一个外表
CREATE TABLE IF NOT EXISTS emp(
	eid VARCHAR(20) PRIMARY KEY,
	ename VARCHAR(20),
	age int ,
	dept_id VARCHAR(20),
	CONSTRAINT emp_fk FOREIGN KEY(dept_id) REFERENCES dept(detpno)
	);
	
-- 	方式二
 CREATE TABLE IF not EXISTS dept2(
	deptno VARCHAR(20) PRIMARY KEY,
	NAME VARCHAR(20) 
	);  
	
	CREATE TABLE IF NOT EXISTS emp2(
	eid VARCHAR(20) PRIMARY KEY,
	ename VARCHAR(20),
	age int ,
	dept_id VARCHAR(20)
	);
	
	ALTER TABLE emp2 add CONSTRAINT emp2_fk FOREIGN key(dept_id) 		REFERENCES dept2(deptno);
	
#外键约束	
INSERT INTO dept
VALUES
	( '1001', '研发部' ),
	( '1002', '销售部' ),
	( '1003', '财务部' ),
	( '1004', '人事部' );
INSERT INTO emp
VALUES
	( '1', '乔峰', 20, '1001' ),
	( '2', '段誉', 21, '1001' ),
	( '3', '虚竹', 23, '1001' ),
	( '4', '阿紫', 18, '1002' ),
	( '5', '扫地僧', 85, '1002' ),
	( '6', '李秋水', 33, '1003' ),
	( '7', '鸠摩智', 50, '1003' ),
	( '8', '天山童姥', 60, '1005' );#这个不能执行由于主表中没有'1005'
	
	#删除数据
-- 	主表的数据被从表依赖时,不能删除,否则可以删除
-- 从表数据可以随意删除
	
	DELETE FROM dept WHERE detpno = '1001';#不可删除
	
	DELETE FROM dept WHERE detpno = '1004';#可以删除
	
	DELETE FROM emp WHERE eid = '7';#可以删除
	
	DELETE FROM emp;#可以删除
	
	
	#删除外键约束
	
	ALTER TABLE emp2 DROP FOREIGN KEY emp2_fk;
	

	#外键约束-多对多关系
	
	use mydb3;
	#创建学生表student(左侧主表)
	
	CREATE TABLE IF not EXISTS student(
	sid int PRIMARY KEY auto_increment,
	name VARCHAR(20),
	age INT,
	gender VARCHAR(20)
	);
	
	  
	#创建课程表course(右侧主表)
	CREATE TABLE course(
	cid int PRIMARY KEY auto_increment,
	cidname VARCHAR(20)
	 );
	 
  #创建中间表student_course/score(从表)
	CREATE TABLE score(
	sid int,
	cid int,
	score DOUBLE
	);
	
-- 	建立外键约束2次
ALTER TABLE score add FOREIGN KEY(sid) REFERENCES student(sid);
ALTER TABLE score add FOREIGN KEY(cid) REFERENCES course(cid);
	
-- 先给学生表添加数据
INSERT INTO student VALUES(1,'小龙女',18,'女'),
													(2,'阿紫',19,'女'),
													(3,'周芷若',20,'男');
-- 再给课程表添加数据
INSERT INTO course VALUES(1,'语文'),(2,'数学'),(3,'英语');

-- 然后给中间表添加数据
INSERT INTO score VALUES(1,1,78),(1,2,75),(2,1,88),(2,3,90),(3,2,80),(3,3,65);
INSERT INTO score VALUES(4,1,99); 	
	
-- 修改和删除时,中间从表可以随便删除和修改,但是两边的主表受从表的依赖的数据不能删除和修改。
	
	
#多表联合查询
	
-- 多表查询-数据准备
 
use mydb3;
-- 创建部门表
create table if not exists dept3(
  deptno varchar(20) primary key ,  -- 部门号
  name varchar(20) -- 部门名字
);
 
-- 创建员工表
create table if not exists emp3(
  eid varchar(20) primary key , -- 员工编号
  ename varchar(20), -- 员工名字
  age int,  -- 员工年龄
  dept_id varchar(20)  -- 员工所属部门
);
 
-- 给dept3表添加数据
insert into dept3 values('1001','研发部');
insert into dept3 values('1002','销售部');
insert into dept3 values('1003','财务部');
insert into dept3 values('1004','人事部');
 
-- 给emp3表添加数据
insert into emp3 values('1','乔峰',20, '1001');
insert into emp3 values('2','段誉',21, '1001');
insert into emp3 values('3','虚竹',23, '1001');
insert into emp3 values('4','阿紫',18, '1001');
insert into emp3 values('5','扫地僧',85, '1002');
insert into emp3 values('6','李秋水',33, '1002');
insert into emp3 values('7','鸠摩智',50, '1002'); 
insert into emp3 values('8','天山童姥',60, '1003');
insert into emp3 values('9','慕容博',58, '1003');
insert into emp3 values('10','丁春秋',71, '1005'); 
 
-- 1.交叉连接查询
/*
1. 交叉连接查询返回被连接的两个表所有数据行的笛卡尔积
2. 笛卡尔集可以理解为一张表的每一行去和另外一张表的任意一行进行匹配
3. 假如A表有m行数据,B表有n行数据,则返回m*n行数据
4. 笛卡尔积会产生很多冗余的数据,后期的其他查询可以在该集合的基础上进行条件筛选
 
格式:select * from 表1,表2,表3….; 
*/
 
-- 内连接查询
/*
  隐式内连接(SQL92标准):select * from A,B where 条件;
  显示内连接(SQL99标准):select * from A inner join B on 条件;
*/
 
 
-- 查询每个部门的所属员工
-- 隐式内连接
select * from dept3,emp3 where dept3.deptno = emp3.dept_id;
select * from dept3 a,emp3 b where a.deptno = b.dept_id;
-- 显式内连接
select * from dept3 inner join emp3 on dept3.deptno = emp3.dept_id;
select * from dept3 a join emp3 b on a.deptno = b.dept_id;
 
-- 查询研发部门的所属员工
-- 隐式内连接
select * from dept3 a ,emp3 b where a.deptno = b.dept_id and name = '研发部'; 
-- 显式内连接
select * from dept3 a join emp3 b on a.deptno = b.dept_id and name = '研发部'; 
 
-- 查询研发部和销售部的所属员工
select * from dept3 a join emp3 b on a.deptno = b.dept_id and (name = '研发部' or name = '销售部') ; 
select * from dept3 a join emp3 b on a.deptno = b.dept_id and name in('研发部' ,'销售部') ; 
 
-- 查询每个部门的员工数,并升序排序
select
    a.name,a.deptno,count(1) 
from dept3 a 
   join emp3 b on a.deptno = b.dept_id 
group by
  a.deptno,name;
 
 
-- 查询人数大于等于3的部门,并按照人数降序排序
 
select
  a.deptno,
  a.name,
  count(1) as total_cnt
from dept3 a
    join emp3 b on a.deptno = b.dept_id
group by
  a.deptno,a.name
having
  total_cnt >= 3
order by
  total_cnt desc;#count(1)中的1代表*的意思
	
	
	#外连接查询
	use mydb3;
-- 	查询那些部门有员工,哪些部门没有就补null
	SELECT * FROM dept3 left OUTER JOIN emp3 on dept3.deptno = emp3.dept_id;
-- 	查询的员工有对应的部门,那些没有就补null
	SELECT * FROM dept3 RIGHT OUTER JOIN emp3 on dept3.deptno = emp3.dept_id;
	
-- 使用union关键字实现左外连接和右外连接的并集就是两个结果合到一张表上
SELECT * FROM dept3 left OUTER JOIN emp3 on dept3.deptno = emp3.dept_id UNION
SELECT * FROM dept3 RIGHT OUTER JOIN emp3 on dept3.deptno = emp3.dept_id;
	
#子查询

-- 子查询就是在一个完整的查询语句中,嵌套若干个不同功能的小查询,从而完成复杂的查询。

#查询最大年龄的员工信息,显示信息包括员工号、员工名字、员工年龄

-- 查询最大年龄
SELECT MAX(age) FROM emp3;

-- 让每一员工的年龄和最大年龄进行比较,相等则条件满足
SELECT * FROM emp3 WHERE age = (SELECT MAX(age) FROM emp3); 
-- 单行单列,可以做一个值使用
#查询研发部和销售部的员工信息,包括员工号、员工名字
-- 方式一关联查询
SELECT * FROM dept3 a JOIN emp3 b on a.deptno = b.dept_id and name in('研发部' ,'销售部') ; 

-- 方式二子查询
-- 先查询研发部和销售部的部门号:deptno 1001和1002
SELECT deptno FROM dept3 WHERE name = '研发部' or name = '销售部';
-- 在查询那个员工的部门号时研发部1001和销售部1002
SELECT * FROM emp3 WHERE dept_id in (SELECT deptno FROM dept3 WHERE name = '研发部' or name = '销售部'
) -- 多行单列

-- 查询研发部20岁以下的员工信息,包括员工工号、员工名字、部门名字
-- 方式一关联查询
SELECT * FROM dept3 a JOIN emp3 b on a.deptno = b.dept_id and (name = '研发部' and age < 20);

-- 方式二子查询
-- 先查询部门表中的研发部信息

SELECT * FROM dept3 WHERE name = '研发部'; -- 一行多列
-- 在员工表中查询年龄小于30岁的员工信息

SELECT * FROM emp3 WHERE age < 30;

-- 最后将这两个结果再进行关联查询
SELECT * FROM (SELECT * FROM dept3 WHERE name = '研发部')  t1 JOIN (SELECT * FROM emp3 WHERE age < 30) t2 ON t1.deptno = t2.dept_id; -- 多行多列


#子查询关键字

#ALL
-- SELECT ... FROM ... WHERE c > ALL(查询语句)等价于:
-- SELECT ... FROM ... WHERE c > result1 and c > result2 and c > result3

-- 查询年龄大于‘1003’ 部门所有年龄的员工信息
SELECT * FROM emp3 WHERE age > ALL(SELECT age FROM emp3 WHERE dept_id = '1003');

-- 查询不属于任何一个部门的信息
SELECT * FROM emp3 WHERE dept_id != ALL(SELECT deptno FROM dept3);

#ANY和some和any是一样的效果
-- SELECT ... FROM ... WHERE c > ANY(查询语句)等价于:
-- SELECT ... FROM ... WHERE c > result1 or c > result2 or c > result3

-- 查询年龄大于'1003'部门任意一个员工年龄的员工信息
SELECT * FROM emp3 WHERE age > ANY(SELECT age FROM emp3 WHERE dept_id = '1003') and dept_id != '1003';

#IN
-- SELECT ... FROM ... WHERE c in (查询语句)等价于:
-- SELECT ... FROM ... WHERE c = result1 or c = result2 or c = result3

-- 查询研发部和销售部的员工信息、包括员工号、员工名字
SELECT eid,ename FROM emp3 WHERE dept_id in (SELECT deptno FROM dept3 WHERE name = '研发部' or name = '销售部');


#EXISTS
-- 查询公司是否大于60岁的员工,有则输出
SELECT * FROM emp3 a WHERE EXISTS(SELECT * FROM emp3 b WHERE a.age > 60);

-- 查询有所属部门的员工信息
SELECT * FROM dept3 a WHERE EXISTS(SELECT * FROM emp3 b WHERE a.deptno = b.dept_id);
#自关联查询

-- SELECT 字段 FROM 表1 a, 表1 b WHERE 条件;
-- 或者
-- SELECT 字段 FROM 表1 a[LEFT] JOIN 表1 b ON 条件;

CREATE TABLE t_sanguo(
	eid INT PRIMARY KEY,
	ename VARCHAR(20),
	manager_id INT,
	FOREIGN KEY (manager_id) REFERENCES t_sanguo (eid) -- 添加自关联约束
	);
	
#添加数据
INSERT INTO t_sanguo VALUES(1,"刘协", null),
														(2,"刘备",1),
														(3,"关羽",2),
														(4,"张飞",2),
														(5,"曹操",1),
														(6,"许诸",5),
														(7,"典韦",5),
														(8,"孙权",1),
														(9,"周瑜",8),
														(10,"鲁肃",8);

#通过关联查询
-- 查询每个三国人物及他的上级信息,如:关羽、刘备
SELECT * FROM t_sanguo a,t_sanguo b WHERE a.manager_id = b.eid;
SELECT a.ename,b.ename FROM t_sanguo a,t_sanguo b WHERE a.manager_id = b.eid;#名字版
SELECT a.ename,b.ename FROM t_sanguo a JOIN t_sanguo b ON a.manager_id = b.eid;

-- 查询所有人物及上级
SELECT a.ename,b.ename FROM t_sanguo a left JOIN t_sanguo b ON a.manager_id = b.eid;
-- 	查询所有人物及上级和上上级
SELECT
 a.ename,b.ename, c.ename
	FROM t_sanguo a
	 left JOIN t_sanguo b ON a.manager_id = b.eid 
	 left JOIN t_sanguo c ON b.manager_id = c.eid;

代码可以直接复制

如果有啥问题可以问我看到一定会回复大家,如果大家喜欢可以作者点赞和关注

大家的支持是我创作下去的最大动力!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值