SQL学习笔记(二)

多表查询

表关系和数据


相关知识点

sql 复制代码
mark ->>> 内连接
- 查询两个表交集的部分

mark ->>> 外连接
- 左外连接, 查询左表所有的数据(包含两个表的交集部分, select * from A left join B, A 是左表, B是右表).
- 右外连接, 查询右表所有的数据(包含两个表的交集部分, select * from A right join B, A 是左表, B是右表, 所有的右连接都可以通过修改顺序变成左连接), 

mark ->>> 自连接
- 当前表自身的连接查询, 自连接必须使用表别名

mark ->>> 联合查询
- 将两次的查询结果合并到一个查询结果中, 要求字段类型和字段列要一致

mark ->>> 子查询
- 标量子查询(子查询的结果为单行单列)
- 列子查询(子查询的结果为多行单列)
- 行子查询(子查询的结果为单行多列)
- 表子查询(子查询的结果为多行多列)

使用示例

sql 复制代码
mark ->>> 内连接

// - 查询员工姓名以及关联的部门名称(隐式, 显示, 显示简写)
// - 隐式
select e.name, d.name from emp as e, dept as d where e.dept_id = d.id;

// -显示
select  e.name, d.name from  emp as e inner join dept as d on e.dept_id = d.id;

// - 显示简写
select  e.name, d.name from  emp as e join dept as d on e.dept_id = d.id;

mark ->>> 外连接
// - 查找emp所有的数据和对应的部门信息(左外)
select e.*, d.name from emp as e left join dept as d on e.dept_id = d.id;

// - 查找emp所有的数据和对应的部门信息(右外)
select d.*, e.* from emp as e left join dept as d on e.dept_id = d.id;

// - 查找emp所有的数据和对应的部门信息(左外)
select d.*, e.* from dept as d left join emp as e on e.dept_id = d.id;

mark ->>> 内连接
// - 查询员工及所属领导的名字
select e.name as 姓名, e1.name as 上司 from emp as e join emp as e1 on e.managerid = e1.id;

// - 查询员工及所属领导的, 所有没有领导, 则显示作者
select e.name as 姓名, case when e1.name is null then '无' else e1.name end as 上司 from emp as e left join emp as e1 on e.managerid = e1.id

// - 查询 年龄在40 - 60 之间 和 dept_id = 1 的人
// - 这里同一个条目会出现两次. 
select * from emp where age > 40 and age < 60 union all select  * from emp where dept_id = 1;

// - 去除重复的条目的. 
select * from emp where age > 40 and age < 60 union select  * from emp where dept_id = 1;

mark ->>> 子查询
// - 查询销售部所有的员工信息
// - 1.查询销售部的id
select id from dept where name = '销售部';

// - 2.查询 dept_id = 4 的员工信息
select * from emp where dept_id = 4;

// - 3.组合最终包含子查询的语句
select * from emp where dept_id = (select id from dept where name = '销售部');

// - 查询在方东白入职之后的入职的员工信息
// - 1.查询方东白的入职日期.
select entrydate from emp where name = '方东白';

// - 2.查询入职日期在 2009-02-12 之后的用户.
select * from emp where entrydate > '2009-02-12';

// - 3.组合最终包含子查询的语句.
select * from emp where entrydate > (select entrydate from emp where name = '方东白');

// - 查询销售部和市场部所有的员工信息
// - 1.查询市场部和销售部的id
select id from dept where name = '销售部' or name = '市场部';

// - 2.查询指定id的员工信息
select * from emp where dept_id in (2,4);

// - 3.组合最终包含子查询的语句
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');

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

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


// - 查询与张无忌薪资相同切与直属领导是同一人的用户
select * from emp where (managerid, salary) = (select managerid, salary from emp where name = '张无忌');

// - 查询与鹿杖客和宋远桥职位相同且薪资相同的用户的信息
select * from emp where (job, salary) in (select job,salary from emp where name in ('鹿杖客', '宋远桥'));

// - 查询入职日期是 2006-01-01 之后的员工的信息及部门信息
// - 错误示范, 有的员工的 dept_id 为 null
-- select e.*, d.* from emp as e, dept as d where e.entrydate > '2006-01-01' and e.dept_id = d.id;

// - 错误示范, 有的员工的 dept_id 为 null
-- select e.*, d.* from emp as e, dept as d where (e.entrydate, d.id) in (select entrydate, dept_id from emp where entrydate > '2006-01-01');

// - 正确写法
select e.*, d.* from (select * from emp where entrydate > '2006-01-01') as e left join dept as d on e.dept_id ==d.id;

// - 查询员工的姓名、年龄、职位、部门信息。
select e.name, e.age, e.job, d.name from emp as e left join dept as d on e.dept_id = d.id;

// - 查询年龄小于30岁的员工姓名、年龄、职位、部门信息。
select e.name, e.age, e.job, d.name from emp as e left join dept as d on e.dept_id = d.id where age < 30;
select e.name, e.age, e.job, d.name from (select * from emp where  age < 30) as e left join dept as d on e.dept_id = d.id;

// - 查询拥有员工的部门ID、部门名称。
// - 外连接, 没有员工的也会被过滤出来
// - select distinct d.id, d.name from dept as d left join emp as e on d.id = e.dept_id;
select distinct d.id, d.name from  dept as d join emp as e on d.id = e.dept_id;

// - 查询所有年龄大于40岁的员工,及其归属的部门名称;如果员工没有分配部门,也需要展示出来。
select  e.*, d.name from (select * from emp where age > 40) as e left join dept as d on e.dept_id = d.id;
select  e.*, d.name from emp as e left join dept as d on e.dept_id = d.id where e.age > 40;

// - 查询所有员工的工资等级。
select e.*, s.grade from emp as e left join salgrade as s on e.salary >= s.losal and e.salary <= s.hisal;
select  e.*, s.grade  from emp as e , salgrade as s where e.salary >= s.losal and e.salary <= s.hisal;

// - 查询"研发部"所有员工的信息及工资等级。
select e.*, s.grade
from (select * from emp where dept_id = (select id from dept where dept.name = '研发部')) as e,
     salgrade as s
where (e.salary >= s.losal and e.salary <= s.hisal)
order by id;

select e.*, s.grade
from (select * from emp where dept_id = (select id from dept where dept.name = '研发部')) as e
         left join salgrade as s
                   on (e.salary >= s.losal and e.salary <= s.hisal)
order by id;

select e.*, s.grade
from emp as e,
     salgrade as s
where (e.salary >= s.losal and e.salary <= s.hisal)
  and dept_id = (select id from dept where dept.name = '研发部')
order by id;

select *
from emp as e,
     salgrade as s,
     dept as d
where (e.salary >= s.losal and e.salary <= s.hisal)
  and d.name = '研发部'
  and e.dept_id == d.id
order by e.id;
                       
// - 查询"研发部"员工的平均工资。
// - 查询工资比"灭绝"高的员工信息。
// - 查询比平均薪资高的员工信息。
// - 查询低于本部门平均工资的员工信息。
// - 查询所有的部门信息,并统计部门的员工人数。
// - 查询所有学生的选课情况,展示出学生名称,学号,课程名称
相关推荐
Huangxy__2 小时前
指针的补充学习
学习
Smartdaili China3 小时前
掌握Java网页抓取:技术与示例完整指南
java·网络·学习·指南·网页·住宅ip·爬虫api
自不量力的A同学4 小时前
OpenNJet v3.3.1.3
笔记
白衣衬衫 两袖清风4 小时前
SQL联查案例
数据库·sql
charlie1145141914 小时前
如何快速在 VS2026 上使用 C++ 模块 — 完整上手指南
开发语言·c++·笔记·学习·现代c++
可信计算5 小时前
【算法随想】一种基于“视觉表征图”拓扑变化的NLP序列预测新范式
人工智能·笔记·python·算法·自然语言处理
历程里程碑5 小时前
C++ 9 stack_queue:数据结构的核心奥秘
java·开发语言·数据结构·c++·windows·笔记·算法
炽烈小老头6 小时前
【每天学习一点算法 2025/12/15】环形链表
学习·算法·链表
晨曦5432107 小时前
MySQL MOD()函数详解与Python对比
sql