MySQL基础知识学习——多表查询(内连接 外连接 自连接)、子查询(四)

多表关系

  • 一对多
    例如:部门与员工的关系 (在多的一方建立外键)
  • 多对多
    列如:学生和课程的关系( 建立中间表 两个外键、一个关联课程一个管理学生)
  • 一对一
    例如:用户和用户详情,多用于单表的拆分

多表查询

内连接 外连接 自连接

内连接查询的是两张表交集的地方;
隐式内连接语法: select 字段列表 from 表1,表2 where 条件…;
显式内连接语法: select 字段列表 from 表1 JOIN 表2 on 连接条件…;
左外连接语法 select 字段列表 from 表1 left join 表2 on 条件;
查询表1的所有数据 包含表1和表2交集的部分数据
右外连接语法 select 字段列表 from 表1 right join 表2 on 条件;
查询表2的所有数据 包含表1和表2交集的部分数据
自连接连接语法 select 字段列表 from 表1 别名A join 表2 别名B on 条件;
自连接查询,可以是内连接查询也可以是外连接查询

create table emp(
    columnId int primary key auto_increment comment '主键',
    username varchar(10) unique not null comment '用户名',
    age int check ( age < 120 && age > 18) comment '年龄',
    dp_id int default '1' comment '部门id',
    vid int default '1' comment '员工id',
    managerId int default '1' comment '经理id',
    grender varchar(1) comment '性别'
) comment '员工表';

insert into emp (username, age, dp_id,vid, managerId, grender) values ('金庸', 40, '2', 1, null, '男'),
                                                        ('张无忌', 30, '1', 2, 1,  '男'),
                                                        ('赵敏', 22, '1', 3, 1,  '男'),
                                                        ('韦一笑', 42, '1',  4, 3, '男'),
                                                        ('周芷若', 30, '3',  5, 3, '男'),
                                                        ('张三丰', 32, '3', 6, 5,  '男'),
                                                        ('李莫愁', 33, '3', 7, 6,  '男');

create table dpTable (
    dp_id int primary key auto_increment,
    name varchar(10) not null unique
) comment '部门表';

insert into dpTable (name) values ('研发部'),('董事长'),('市场'),('后勤'),('总经办');


# 内连接
select * from emp, dpTable where emp.dp_id = dpTable.dp_id;
# 内连接带别称
select e.username,d.name from  emp as e, dpTable as d where e.dp_id = d.dp_id;
# 内连接显示链接  select -- frome table1 join table2 on 条件
select * from emp e join dptable d on e.dp_id = d.dp_id;

# 外连接  左连接会查询两个集合重复的部分和整个坐标的库。 同样右链接也是 select -- frome table1 right join table2 on 条件
select * from emp e LEFT JOIN dptable d on e.dp_id = d.dp_id;
select d.name, e.username from emp e right JOIN dptable d on e.dp_id = d.dp_id;

# 自链接  就是一张表当成两张表来查
select a.username as '员工', b.username as '领导' from emp a, emp b where a.managerId = b.vid;

子查询

定义

SQL语句中嵌套SELECT语句,称为嵌套查询或子查询;先执行内嵌套条件再执行外部条件。
子查询的外部语句可以是insert、update、delete、select

多表查询——子查询

根据子查询结果不同分为:
标量子查询——结果为单个值
列子查询——结果为一列
行子查询——结果为一行
表子查询——结果为多行多列

select * from emp.e,dpTable d where e.dp_id=d.dp_id and d.name='研发部';

子查询(匹配一个值)

= 匹配一个值

select * from emp where dp_id=(select dp_id  from  dpTable d where name='研发部' );

子查询(匹配多个值)

in 匹配多个值

select * from emp where dp_id in(select dp_id  from  dpTable d where name='研发部'or name='董事' );

子查询实例(去重、不去重、标量子、列子、行子查询)

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);


drop table dptable;
drop table emp;

# union all 是不去重的。 union 去重
select * from emp where salary < 5000
union
select * from emp where age > 50;

select * from emp where salary < 5000
union all
select * from emp where age > 50;

# 子链接
# 查询所有销售部门的员工信息
select * from emp where emp.dept_id = (select id from dept where dept.name = '销售部');
-- 2. 查询在 "方东白" 入职之后的员工信息
select * from emp where emp.name = '方东白';
select * from emp where emp.entrydate > (select entrydate from emp where emp.name = '方东白');

-- 列子查询
-- 1. 查询 "销售部""市场部" 的所有员工信息
select e.* from emp as e where e.dept_id in (select d.id from  dept as d where d.name = '市场部' or  d.name = '销售部');

-- 2. 查询比 财务部 所有人工资都高的员工信息
select * from emp where salary > all ( select salary from emp where dept_id = (select id from dept where name = '财务部') );

-- 3. 查询比研发部其中任意一人工资高的员工信息
select * from emp where salary > some ( select salary from emp where dept_id = (select id from dept where name = '研发部') );

-- 行子查询
-- 1. 查询与 "张无忌" 的薪资及直属领导相同的员工信息 ;
select * from emp where (emp.salary, emp.managerid) = (select salary, managerid from emp where emp.name = '张无忌');

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

-- 2. 查询入职日期是 "2006-01-01" 之后的员工信息 , 及其部门信息
select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept_id = d.id ;

猜你喜欢

转载自blog.csdn.net/weixin_45496521/article/details/128984555
今日推荐