已更新!宝藏教程!MYSQL-第六章节多表查询(一对一,多对多,一对多),连接查询(内,外连接),联合查询,子查询 代码例题详解这一篇就够了(附数据准备代码)

c++知识点合集已经完成欢迎前往主页查看,点点赞点点关注不迷路哦

点我进入c++第一章知识点合集

MYSQL第一章节DDL数据定义语言的操作 ----点我进入

MYSQL第二章节DDL-数据库操作语言 DQL-数据查询语言---- 点我进入

MYSQL第三章节DCL-管理用户,控制权限---- 点我进入

MYSQL第四章节常用函数说明---- 点我进入

MYSQL第五章节有关约束操作详解---- 点我进入

MYSQL-第六章节多表查询

目录

多表查询

多对多

[例子 :将学生表与课程表建立联系](#例子 :将学生表与课程表建立联系)

一对一

例子

多表查询例题

[多表查询 -- 笛卡尔积](#多表查询 -- 笛卡尔积)

连接查询-内连接

隐式内连接

显示内连接

例子

连接查询-外连接

左外连接

右外连接

例子

连接查询-自连接

例题

[联合查询 -unio,unio all](#联合查询 -unio,unio all)

例子

子查询

标量子查询

例子

列子查询

例子


多表查询

多表查询基本分为三种(一对多,多对多,一对一)

多对多

对于多对多的关系而言应该需要建立第三张中间表,中间表至少包含两个外键,分别关联两个主键

例子 :将学生表与课程表建立联系

​创建学生表

sql 复制代码
CREATE TABLE studen (
id int auto_increment primary key comment '主键id',
name varchar(50),
no int 
)comment '学生表';
insert into student (name,no)  values ('黛绮丝',200100101),('谢逊',200100102),('嬴政天',200100103),('韦一笑',200100104);

创建课程表

sql 复制代码
CREATE TABLE course(
id int auto_increment primary key comment '主键id',
name varchar(50) comment '课程名称'
)comment '课程表';
insert into course VALUES (NULL,'JAVA'),(NULL,'PHP'),(NULL,'Mysql'),(null,'hadoop');

建立第三张表(学生课程关系表)并于上面两张表关联

sql 复制代码
CREATE TABLE student_course(
id int auto_increment primary key comment '主键id',
studentid int not null comment '学生id', 
courseid int not null comment '课程id',
constraint fk_studentid FOREIGN KEY (studentid) REFERENCES student(id),
constraint fk_courseid foreign key (courseid) references course(id)
)comment '学生课程中间表';
insert into student_course (studentid,courseid) values(1,1),(1,2),(1,3),(2,1),(2,4);

一对一

在任意一方加入外键,关联另一方的主键,并且设置外键的唯一约束(UNIQUE)

例子

创建用户基本信息表

sql 复制代码
CREATE TABLE tb_user(
id int auto_increment primary key comment '主键id',
name varchar(50) comment '姓名',
age int comment '年龄',
gender char(1) comment '性别',
phone varchar(11) comment '电话号码'
)comment '用户基本信息表';
insert into tb_user (name,age,gender,phone) values('黄渤',45,'1','17263648590'),('冰冰',35,'2','17276448590'),
('码云',55,'1','17364950374'),('李彦宏',50,'1','17263495064');

创建用户教育信息表并添加外键约束

sql 复制代码
CREATE TABLE tb_user_edu(
id int auto_increment primary key ,
degree char(2),
major varchar(50),
primaryschool  varchar(50),
middleschool varchar(50),
university varchar(50),
userid int,
constraint fk_userid foreign key (userid) references tb_user(id)
)
insert into tb_user_edu (degree,major,primaryschool,middleschool,university,userid) values
('本科','舞蹈','静安区第一小学','静安区第一中学','北京舞蹈学院',1),
('硕士','表演','朝阳区第一小学','朝阳区第一中学','北京电影学院',2),
('本科','英语','杭州市第一小学','杭州市第一中学','杭州师范大学',3),
('本科','应用数学','阳泉第一小学','阳泉第一中学','清华大学',3);

多表查询例题

数据准备

sql 复制代码
-- 准备数据
create table dept(
    id   int auto_increment comment 'ID' primary key,
    name varchar(50) not null comment '部门名称'
)comment '部门表';

create table emp(
    id  int auto_increment comment 'ID' primary key,
    name varchar(50) not null comment '姓名',
    age  int comment '年龄',
    job varchar(20) comment '职位',
    salary int comment '薪资',
    entrydate date comment '入职时间',
    managerid int comment '直属领导ID',
    dept_id int comment '部门ID'
)comment '员工表';

-- 添加外键
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);

INSERT INTO dept (id, name) VALUES (1, '研发部'), (2, '市场部'),(3, '财务部'), (4, '销售部'), (5, '总经办'), (6, '人事部');
INSERT INTO emp (id, name, age, job,salary, entrydate, managerid, dept_id) VALUES
            (1, '金庸', 66, '总裁',20000, '2000-01-01', null,5),

            (2, '张无忌', 20, '项目经理',12500, '2005-12-05', 1,1),
            (3, '杨逍', 33, '开发', 8400,'2000-11-03', 2,1),
            (4, '韦一笑', 48, '开发',11000, '2002-02-05', 2,1),
            (5, '常遇春', 43, '开发',10500, '2004-09-07', 3,1),
            (6, '小昭', 19, '程序员鼓励师',6600, '2004-10-12', 2,1),

            (7, '灭绝', 60, '财务总监',8500, '2002-09-12', 1,3),
            (8, '周芷若', 19, '会计',48000, '2006-06-02', 7,3),
            (9, '丁敏君', 23, '出纳',5250, '2009-05-13', 7,3),

            (10, '赵敏', 20, '市场部总监',12500, '2004-10-12', 1,2),
            (11, '鹿杖客', 56, '职员',3750, '2006-10-03', 10,2),
            (12, '鹤笔翁', 19, '职员',3750, '2007-05-09', 10,2),
            (13, '方东白', 19, '职员',5500, '2009-02-12', 10,2),

            (14, '张三丰', 88, '销售总监',14000, '2004-10-12', 1,4),
            (15, '俞莲舟', 38, '销售',4600, '2004-10-12', 14,4),
            (16, '宋远桥', 40, '销售',4600, '2004-10-12', 14,4),
            (17, '陈友谅', 42, null,2000, '2011-10-12', 1,null);

多表查询 -- 笛卡尔积

sql 复制代码
select * from emp , dept where emp.dept_id = dept.id; 

连接查询-内连接

隐式内连接

sql 复制代码
SELECT 字段列表 FROM 表1,表2 WHERE 条件...;

显示内连接

sql 复制代码
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件...;

内连接是两张表交集的部分

例子

数据见上面的数据准备

查询每一位员工的姓名,以及关联部门的名称(隐示内连接实现 )

sql 复制代码
SELECT emp.name,DEPT.name FROM emp,dept WHERE emp.dept_id = dept.id;

数据见上面的数据准备

查询每一位员工的姓名,以及关联部门的名称(显示内连接实现 )

sql 复制代码
SELECT emp.name ,dept.name from emp join dept on emp.dept_id = dept.id;

连接查询-外连接

左外连接

sql 复制代码
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件...;

相当于查询表1(左表)的所有数据包含表1和表2的所有数据

右外连接

sql 复制代码
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件...;

相当于查询表2(右表)的所有数据包含表1和表2的所有数据

例子

数据见上面的数据准备

查询emp表的所有数据,和对应部门的信息(左外连接)

sql 复制代码
select emp.*,dept.name from emp left outer join dept on emp.dept_id = dept.id;

数据见上面的数据准备

查询dept表的所有数据,和对应员工的信息(右外连接)

sql 复制代码
select dept.* ,emp.* from dept right outer join emp on emp.dept_id = dept.id;

连接查询-自连接

sql 复制代码
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件...;

自连接查询,可以是内连接查询,也可以是外连接查询。

例题

查询每个员工直属领导的名字

sql 复制代码
SELECT a.name,b.name FROM emp a,emp b where a.managerid=b.id;

查询所有员工及其领导的名字,如果员工没有领导,也需要查询出来

sql 复制代码
SELECT a.name,b.name FROM emp a left join dept b on a.managerid=b.id;

联合查询 -unio,unio all

对于unio查询,就是把多次查询的结果组合起来,形成一个新的查询结果

sql 复制代码
SELECT 字段名 FROM 表A...
UNION [ALL]
SELECT 字段名 FROM 表B...;

例子

将薪资低于5000的员工,和年龄大于50岁的员工全部查寻出来

sql 复制代码
SELECT * FROM emp where salary <5000
union all
SELECT * FROM emp where age>50;

有查询出来但是出现了重复的数据我们可以做如下修改

sql 复制代码
SELECT * FROM emp where salary <5000
union 
SELECT * FROM emp where age>50;


注意:

联合查询的多张表需要保持一致,字段类型也需要保持一致。

union all 会将全部数据直接合并在一起,union会对合并以后的数据去重。

子查询

子查询又称为嵌套查询SQL语句里面嵌套SELECT语句

sql 复制代码
SELECT * FROM T1 WHERE COLUMN1 = (SELECT COULMN1 FROM T2);

子查询外部的语句可以是INSERT/DPDATE/DELETESELECT的任何一个

根据子查询的结果不同,分为:

标量子查询(结果为单个值)

列子查询(结果为一列)

行子查询(结果为一行)

表子查询(结果为多行或者多列)

标量子查询

常用操作符:= <> > >= < <=

例子

数据准备见上面的数据准备代码

查询销售部的所有员工信息

sql 复制代码
--查询销售部的所有员工信息--

--查询销售部门的id
SELECT id FROM dept where name='销售部';

--根据销售部门的id来查询员工信息--
SELECT * FROM emp where (SELECT id FROM dept where name='销售部');

查询"方东白"入职之后的员工信息

sql 复制代码
--查询"方东白"入职之后的员工信息--

--查询房东白的入职时间--
 SELECT ENTRYDATE FROM EMP WHERE NAME='方东白';
 
 --查询指定日期之后的入职员工--
 SELECT * FROM emp WHERE entrydate > ( SELECT ENTRYDATE FROM EMP WHERE NAME='方东白');

列子查询

常用操作符:IN NOT IN ANY SOME ALL

例子

查询销售部和市场部的所有员工信息

sql 复制代码
 --查询销售部和市场部的所有员工信息--
 
 --查询销售部和市场部的id--
 SELECT ID FROM dept WHERE NAME='销售部'or name='市场部';
 
 ----根据id查询销售部和市场部的所有员工信息--
 SELECT * FROM emp where dept_id in ( SELECT ID FROM dept WHERE NAME='销售部'or name='市场部');

查询比财务部所有员工工资都高的员工信息

sql 复制代码
 -- 查询比财务部所有员工工资都高的员工信息--
 
 --查询财务部的id
 SELECT id FROM DEPT WHERE NAME='财务部';
 
 --查询ID查询财务部所有员工的工资--
 SELECT salary from emp where dept_id=(SELECT id FROM DEPT WHERE NAME='财务部');
 
 --查询比财务部所有员工工资都高的员工信息--
 SELECT * FROM emp where salary >all(SELECT salary from emp where dept_id=(SELECT id FROM DEPT WHERE NAME='财务部'));

查询比研发部任意员工工资都高的员工信息

sql 复制代码
 -- 查询比研发部任意员工工资高的员工信息--
 
 --查询研发部的id
 SELECT id FROM DEPT WHERE NAME='研发部';
 
 --查询ID查询研发部所有员工的工资--
 SELECT salary from emp where dept_id=(SELECT id FROM DEPT WHERE NAME='研发部');
 
 --查询比研发部任意员工工资高的员工信息--
 SELECT * FROM emp where salary >any(SELECT salary from emp where dept_id=(SELECT id FROM DEPT WHERE NAME='研发部'));

行子查询

常用穿制符号 = <> IN NOT IN

例子

查询与张无忌的薪资及直属领导相同的员工信息

sql 复制代码
--查询与张无忌的薪资及直属领导相同的员工信息--

--查询张无忌的薪资以及直属领导--
SELECT salary,managerid  FROM emp where name='张无忌';

--查询与张无忌的薪资及直属领导相同的员工信息--
SELECT * FROM emp where (salary,managerid)=(SELECT salary,managerid  FROM emp where name='张无忌');

表子查询

常用操作符: IN

--查询与鹿杖客,宋远桥的职位和薪资相同的员工信息--

sql 复制代码
--查询鹿杖客,宋远桥的职位和薪资--
SELECT salary,job FROM emp where name='鹿杖客'or name='宋远桥';

--查询与鹿杖客,宋远桥的职位和薪资相同的员工信息--
SELECT * FROM emp where (salary,job)in(SELECT salary,job FROM emp where name='鹿杖客'or name='宋远桥');

查询入职日期是"2006-01-01"之后的员工信息,及其部门信息

sql 复制代码
--查询入职日期是"2006-01-01"之后的员工信息,及其部门信息 --

--查询入职日期是"2006-01-01"之后的员工信息--
SELECT * FROM emp where entrydate>'2006-01-01';

--查询入职日期是"2006-01-01"之后的员工信息,及其部门信息 --
SELECT * FROM (SELECT * FROM emp where entrydate>'2006-01-01') a,DEPT WHERE (a.dept_id=dept.id);
相关推荐
欧阳枫落1 分钟前
python 2小时学会八股文-数据结构
开发语言·数据结构·python
何曾参静谧8 分钟前
「QT」文件类 之 QTextStream 文本流类
开发语言·qt
monkey_meng12 分钟前
【Rust类型驱动开发 Type Driven Development】
开发语言·后端·rust
落落落sss20 分钟前
MQ集群
java·服务器·开发语言·后端·elasticsearch·adb·ruby
2401_8532757340 分钟前
ArrayList 源码分析
java·开发语言
zyx没烦恼41 分钟前
【STL】set,multiset,map,multimap的介绍以及使用
开发语言·c++
lb363636363641 分钟前
整数储存形式(c基础)
c语言·开发语言
feifeikon43 分钟前
Python Day5 进阶语法(列表表达式/三元/断言/with-as/异常捕获/字符串方法/lambda函数
开发语言·python
爪哇学长1 小时前
SQL 注入详解:原理、危害与防范措施
xml·java·数据库·sql·oracle
大鲤余1 小时前
Rust,删除cargo安装的可执行文件
开发语言·后端·rust