sql入门-多表查询

案例涉及表

sql入门-多表查询_第1张图片

sql入门-多表查询_第2张图片

sql入门-多表查询_第3张图片

 ----------------------------------建表语句之前翻看之前博客文章

sql入门-多表查询_第4张图片

 sql入门-多表查询_第5张图片

 sql入门-多表查询_第6张图片

多表查询

sql入门-多表查询_第7张图片

-- 学生表
create table studen (
    id int primary key auto_increment comment 'id',
    name varchar(50) comment '姓名',
    no varchar(10) comment '学号'
) comment '学生表';

insert into studen values (null , '黛绮丽','2000100101'),(null , '谢逊','2000100102'),(null , '殷天正','2000100103'),(null , '韦一笑','2000100184');

drop table studen;

use itheima;

-- 课程表
create table course(
    id int auto_increment primary key comment 'id',
    name varchar(10) comment '课程名称'
)comment '课程名称';

insert into course values (null,'java'),(null,'php'),(null,'mysql'),(null,'hadoop');

-- 中间表(连接两种表上的关系)
create table studen_course(
    id int primary key auto_increment comment 'id',
    studen_id int not null comment '学生id',
    course_id int not null comment '课程id',
    constraint wj_studen foreign key(studen_id) references studen(id),
     constraint wj_course foreign key(course_id) references course(id)
) comment '学生课程中间表';

insert into studen_course values(null,1,1),(null,1,2),(null,1,3),(null,1,4);

-- 多表查询需要消除笛卡尔积

-- 内连接    **--两张表交集部分
-- -- 隐式内连接  select 字段列表 表1,表2 where 条件


-- -- 显示内连接  select 字段列表 from 表1 [inner]join 被连接的表 on 连接条件
-- inner

-- 外连接  **-- 左外 相当于查询所有左表数据  并包含表1和表2 交集部分数据     右外同理
-- -- 左外连接  select 字段 from 表1 left[outer] join 表2 no 条件 ...
# 1.查询emp所有数据,和对应部门信息
select e.*,d.name from emp e left join dept d on e.det_id = d.id;

-- -- 右外连接  select 字段 from 表1 right[outer]join 表2 on 条件...
-- outer可以省略


-- 自连接查询  select 字段 from 表a 别名a join 表a 别名b on 条件...
# **-- 自连接查询,可以是内连接查询,也可以是外连接查询
#1. 查询员工并获取 及其领导的名字
select * from emp;

select e1.name 员工姓名 ,e1.age 年龄 , e2.name 领导名称  from emp e1 join emp e2 on e1.mangerid = e2.id;

#2. 查询员工并获取 及其领导的名字(没有领导也要显示出来) -- 使用左侧连接即可
select e1.name 员工姓名 ,e1.age 年龄 , e2.name 领导名称  from emp e1 left join emp e2 on e1.mangerid = e2.id;


-- 联合查询  select 字段 from 表a  unino[all] select 字段 from 表b ....
-- union 合并查询结果
-- union all 合并结果,并去重
# 1.薪资小于 5000 和 年龄大于50

-- union 会去重 猪八戒只出现一次
select * from emp where salary < 5000
union
select * from emp where age > 50;

-- 猪八戒 会重复出现两次 语法 union all 合并两次查询结果(不去重
select * from emp where salary < 5000  -- 猪八戒符合条件
union all
select * from emp where age > 50;  -- 猪八戒符合条件

-- 子查询  sql嵌套select 语句 称为嵌套查询 又称子查询
-- select * from t1 where column1 = (select column1 from t2)
-- 子查询外部可以是 inster update delete select任何一个

-- --  标量子查询(子查询结果为单个值)
# -- 常用的操作符  =等于  <>不等  >大于  >=大于等于 <小于  <=小于等于
# 查询销售部所有员工
select * from emp where det_id = (select id from dept where name = '销售部');

-- --  列子查询(查询结果为一列)
# -- 常用操作符 in指定范围内 not in指定范围外
# -- any子查询任意一个满足即可 some和any等同  all子查询返回列表所有值必须满足
# 查询比 销售部 所有人工资都高的员工信息
select id from dept where name = '销售部';
select salary from emp where det_id = (select id from dept where name = '销售部');
select * from emp where salary > all (select salary from emp where det_id = (select id from dept where name = '销售部'));

-- --  行子查询(查询结果为一行)
# -- 常用操作符 =  <>  in  not in
# 查询和 杨逍 的 薪资 及 直属领导 相同的员工
select salary , mangerid from emp where name = '杨逍' ;

select * from emp where (salary , mangerid) = (select salary , mangerid from emp where name = '杨逍');


-- -- 表子查询(查询结果为多行多列)
# 常用操作符  in
# 查询 宋远桥  和 鹿杖客 职位相同和薪资相同的员工
select salary , job from emp  where name = '宋远桥' || name = '鹿杖客';

select * from emp where (salary , job) in (select salary , job from emp  where name = '宋远桥' || name = '鹿杖客');

# 查询入职日期 '2006-01-01'之后的员工信息,及其部门信息
select id,det_id from emp where entrydate > '2006-01-01';
select e.* , d.name from emp e ,dept d where (e.id , d.id) in (select id,det_id from emp where entrydate > '2006-01-01');

select * from emp where entrydate > '2006-01-01';
select * from (select * from emp where entrydate > '2006-01-01') e left join emp d on e.det_id = d.id;

# -- -- 根据子查询位置,分为where之后,from之后,select之后


# ========================多表查询案例=======================
create table salgrade (
    grade int ,
    losal int ,
    hisal int
) comment '薪资等级表';

insert into salgrade values (1,0,3000);
insert into salgrade values (2,30001,5000);
insert into salgrade values (3,5001,8000);
insert into salgrade values (4,8001,10000);
insert into salgrade values (5,10001,15000);
insert into salgrade values (6,15001,20000);
insert into salgrade values (7,20001,25000);
insert into salgrade values (8,25001,30000);

# 1. 查询员工的姓名 年龄 职位  部门信息
select name , age , job ,det_id  from emp;
-- 隐式内连接--35ms
select e.name ,e.age ,e.job,d.name from dept d , emp e where e.det_id = d.id;
-- 显示外连接--28ms  外连接  左连接  查询交际部分-且返回左侧表所有
select e.name ,e.age ,e.job,d.name from  emp e left join dept d on d.id = e.det_id;



# 2.查询年龄小于30岁的员工姓名,年龄 职位,部门信息(显示内连接)
select * from emp where age < 30;
-- 隐式内连接
select e.name ,e.age ,e.job,d.name from emp e ,dept d where e.age < 30  and  e.det_id = d.id;
-- 显示内连接  -inner join  on   只查询交际部分
select * from emp e inner join dept d on e.det_id = d.id where e.age < 30;

# 3.查询所有员工的部门id,部门名称
-- distinct 去重
select distinct d.* from dept d , emp e where d.id = e.det_id;

# 4.查询所有年龄大于40岁的员工,及其部门的名称,如果员工没有部门,也需要展示出来
select e.* , d.name from emp e left join dept d on e.det_id = d.id where age > 40;

# 5.查询所有员工的工资的等级
select e.salary ,s.grade from emp e , salgrade s where e.salary between s.losal and s.hisal;

# 6.查询研发部所有员工信息及工资等级
select id from dept where name = '研发部';

select * from emp where det_id = (select id from dept where name = '研发部');
-- 子查询方法完成
select e.*, s.grade
from (select * from emp where det_id = (select id from dept where name = '研发部')) e,
     salgrade s
where e.salary between s.losal and s.hisal;

-- 内连接方法
select *
from emp e,
     dept d,
     salgrade s
where e.det_id = d.id
  and e.salary between s.losal and
    s.hisal
  and d.name = '研发部';

# 7.查询‘研发部员’ 工的 ’平均工资‘   -- 聚合函数 avg  平均值
select avg(e.salary)
from emp e ,dept d where e.det_id = d.id and d.name = '研发部';

# 8.查询工资比 '常遇春' 高的员工信息
select salary from emp where name = '常遇春';

select * from emp e where e.salary > (select salary from emp where name = '常遇春');

# 9.查询比平均工资高的员工信息
select avg(salary) from emp ;

select * from emp e where e.salary > (select avg(salary) from emp) ;

# 10.查询低于本部门平均工资的员工信息
-- a思路 ** 当前指定部门的平均薪资
select avg(salary) from emp where det_id = 1;

-- b  此处考察执行顺序  首先from e1   条件薪资小于  指定部门平均薪资
select e1.* , (select avg(salary) from emp where det_id = e1.det_id) 部门平均薪资
from emp e1
where e1.salary < (select avg(salary) from emp where det_id = e1.det_id);


# 11.查询所有的部门信息,并统计部门的员工人数
-- 获取指定部门统计人数
select count(*)
from emp where det_id = 1;
-- 统计部门人数
select d.name ,d.id ,(select count(*)from emp e where e.det_id = d.id ) 部门人数 from dept d;

# 12.查询所有学生 的选则课情况 展示学生名称 ,学号,课程名称
-- 涉及表 studen course stunden_course

select s.name, s.no, c.name
from studen s,
     studen_course sc,
     course c
where s.id = sc.studen_id
  and c.id = sc.course_id;

你可能感兴趣的:(sql,数据库)