Java学习路线-42:SQL进阶:约束、关系、连接

举报
彭世瑜 发表于 2021/08/13 23:17:34 2021/08/13
【摘要】 SQL进阶:约束、关系、连接 课时1 1.单表的查询练习 可视化客户端 SQLyog -- 查询部门编号为30的所有员工 select * from emp where deptno=30; -- 查询所有销售员的姓名、编号和部门编号 select ename, empno, deptno from emp where job='销售员' -- 查询奖金高于工...

SQL进阶:约束、关系、连接

课时1 1.单表的查询练习

可视化客户端 SQLyog

-- 查询部门编号为30的所有员工
select * from emp where deptno=30;

-- 查询所有销售员的姓名、编号和部门编号
select ename, empno, deptno from emp where job='销售员'

-- 查询奖金高于工资的员工
select * from emp where comm > sal;

-- 查询奖金高于工资60%的员工
select * from emp where comm > sal * 0.6;

-- 查询部门编号为10中所有经理,和部门编号编号为20中所有销售员的详细资料
select * from emp 
where (deptno=10 and job='经理')
or (deptno=20 and job='销售员');

-- 查询部门编号为10中所有经理,和部门编号编号为20中所有销售员,
-- 还有既不是经理又不是销售员但工资大于等于20000的所有员工详细资料
select * from emp 
where (deptno=10 and job='经理')
or (deptno=20 and job='销售员')
or (job not in ('经理', '销售员') and sal >= 2000);

-- 无奖金或奖金低于1000的员工
select * from emp where comm is null or comm < 1000;

-- 查询名字由3个字组成的员工(3个下划线)
select * from emp where ename like '___';

-- 查询2000年入职的员工
select * from emp where hiredate like '2000-%';

-- 查询所有员工,用编号升序排序
select * from emp order by empno asc;

-- 查询所有员工详细信息,用工资降序排序,如果工资相同使用入职日期升序排序
select * from emp order by sal desc, hiredate asc;

-- 查询每个部门的平均工资
select deptno, avg(sal) from emp group by deptno;

-- 查询每个部门雇员数量
select deptno, count(*) from emp group by deptno;

-- 查询每种工作的最高工资,最低工资,人数
select job, max(sal), min(sal), count(*) from emp group by job;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

课时2 2.mysql编码问题

-- 查看MySQL的数据库编码
show variables like 'char%';

-- 临时设置变量
set character_set_client=utf8
set character_set_results=utf8

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

永久设置:
my.ini中配置

课时3 3.mysql备份与恢复数据库

1、备份:数据库->SQL语句

$ mysqldump -u用户名 -p密码 数据库名 > 要生成的SQL脚本路径

  
 
  • 1

2、恢复:SQL语句->数据库

$ mysql -u用户名 -p密码 数据库名 < 要生成的SQL脚本路径

# 或者
> source 要生成的SQL脚本路径

  
 
  • 1
  • 2
  • 3
  • 4

课时4 4.约束之主键约束

特点:唯一,非空,被引用

指定id列为主键列

-- 1、创建表时指定主键
create table stu( id int primary key, name varchar(20)
)

-- 或者
create table stu( id int, name varchar(20), primary key(id)
)

-- 2、已存在表添加主键
alter table stu add primary key(id);

-- 3、删除主键
alter table stu drop primary key;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

课时5 5.主键自增长

保证插入数据时主键唯一非空

-- 1、创建表时指定主键自增长
create table stu( id int primary key auto_increment, name varchar(20)
)

-- 设置字段自增长
alter table stu change id id int auto_increment;

-- 删除自增长
alter table stu change id id int;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

uuid作为主键

课时6 6.非空和唯一约束

非空约束:不能为null
not null

唯一约束:不能重复
unique

create table stu( id int primary key auto_increment, name varchar(20) not null unique 
)

  
 
  • 1
  • 2
  • 3
  • 4

课时7 7.概述模型、对象模型、关系模型

1、对象模型
is a 继承
has a 关联 1对1 1对多 多对多
use a

2、关系模型
数据库中的表

代码实现

// 一对一关系 丈夫-妻子
class  Husband{ private Wife wife;
}

class Wife{ private Husband husband;
}

// 一对多关系 部门-员工
class Employee{ private Department department;
}

class Department{ private List<Employee> employee;
}

// 多对多关系 老师-学生
class Student{ private List<Teacher> teachers
}

class Teacher{ private List<Student> students
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

外键约束
外键引用主键,必须引用另一张表主键
外键可以重复
外键可以为空
一张表中可以有多个外键

课时8 8.外键约束

create table dept( deptno int primary key auto_increment, dname varchar(50)
)

insert into dept values(10, '人力部');
insert into dept values(20, '研发部');
insert into dept values(30, '财务部');

-- 创建表时添加外键约束
create table emp( empno int primary key auto_increment, ename varchar(50), dno int, constraint fk_emp_dept foreign key(dno) references dept(deptno)
)

-- 添加外键约束
alter table emp add constraint fk_emp_dept foreign key(dno) references dept(deptno)

insert into emp(ename) values('张三');
insert into emp(ename, dno) values('李四', 10);
insert into emp(ename, dno) values('王五', 20);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

课时9 9.一对一关系

从表的主键就是外键

create table husband( hid int primary key auto_increment, hname varchar(50)
)

insert into husband(hname) values ('刘备'), ('关羽'), ('张飞')

create table wife( wid int primary key auto_increment, wname varchar(50), constraint fk_wife_husband foreign key(wid) references husband(hid)
)
-- wid 非空,唯一,引用hid

insert into wife(wid, wname) values(1, '杨贵妃');
insert into wife(wid, wname) values(2, '西施');


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

课时10 10.多对多关系

create table student( sid int primary key auto_increment, sname varchar(50)
)

create table teacher( tid int primary key auto_increment, tname varchar(50)
)

create table stu_tea( sid int, tid int, constraint fk_student foreign key(sid) references student(sid), constraint fk_teacher foreign key(tid) references teacher(tid)
)

insert into student(sname) values('段誉');
insert into student(sname) values('乔峰');
insert into student(sname) values('虚竹');

insert into teacher(tname) values('黄老师');
insert into teacher(tname) values('刘老师');
insert into teacher(tname) values('李老师');

insert into stu_tea(sid, tid) values(1, 1);
insert into stu_tea(sid, tid) values(2, 1);
insert into stu_tea(sid, tid) values(3, 1);

insert into stu_tea(sid, tid) values(1, 2);
insert into stu_tea(sid, tid) values(3, 2);

insert into stu_tea(sid, tid) values(1, 3);
insert into stu_tea(sid, tid) values(2, 3);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

课时11 11.合并结果集

要合并的结果集表结构一样(列数, 列类型)

create table tb_a(id int, a_name varchar(50));
insert into tb_a(id, a_name) values(1, '1');
insert into tb_a(id, a_name) values(2, '2');
insert into tb_a(id, a_name) values(3, '3');

create table tb_b(id int, b_name varchar(50));
insert into tb_b(id, b_name) values(3, '3');
insert into tb_b(id, b_name) values(4, '4');
insert into tb_b(id, b_name) values(5, '5');

-- 不合并重复行
select * from tb_a union all select * from tb_b;

-- 合并重复行
select * from tb_a union select * from tb_b;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

课时12 12.连接查询之内连接(方言)

-- 方言
select * from1 别名1,2 别名2 where 别名1.xx = 别名2.xx;

-- 标准 (推荐)
select * from1 别名1 inner join2 别名2 on 别名1.xx = 别名2.xx;

-- 自然
select * from1 别名1 natural join2 别名2

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

笛卡尔积:

(a, b, c) X (1, 2)

-> 
a1, a2, b1, b2, c1, c2

  
 
  • 1
  • 2
  • 3
  • 4
-- 笛卡尔积
select * from emp, dept

-- 员工对应部门信息
select * from emp, dept where emp.dno=dept.deptno;

-- 打印所有员工的姓名,部门名称, 取别名
select e.ename, d.dname
from emp e, dept d
where e.dno=d.deptno;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

课时13 13.连接查询之内连接(标签和自然)

-- 标准推荐
select * from emp inner join dept on emp.dno=dept.deptno;

-- 自动加where条件
select * from emp natural join dept

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

课时14 14.连接查询之外连接

主表中所有记录都会打印, 副表没有null补位

-- 左外连接, 左表为主
select e.ename, ifnull(d.dname, '无部门') as dname
from emp e left outer join dept d
on e.dno=d.deptno;

-- 右外连接, 右表为主
select e.ename, d.dname
from emp e right outer join dept d
on e.dno=d.deptno;

-- 全外连接
select e.ename, d.dname
from emp e left outer join dept d
on e.dno=d.deptno;
union
select e.ename, d.dname
from emp e right outer join dept d
on e.dno=d.deptno;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

课时15 15.子查询

查询中有查询

-- 查询本公司工资最高的员工详细信息
select * from emp where sal=(select max(sal) from emp);

  
 
  • 1
  • 2

子查询出现的位置

from 后作为表存在(多行多列)
where 后作为条件存在

  
 
  • 1
  • 2

条件

-- 单行单列 
select * from1 别名1 where1[=, >, <, >=, <=, !=]
(selectfrom2 别名2 where 条件)

-- 多行单列
select * from1 别名1 where1[in, all, any]
(selectfrom2 别名2 where 条件)

-- 单行多列(一个对象)
select * from1 别名1 where (1,2) in
(select1,2 from2 别名2 where 条件)

-- 多行多列
select * from1 别名1, 
(select ...) 别名2 where 条件

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

eg:

-- 工资高于平均工资的员工
select * from emp where sal > (select avg(sal) from emp);

-- 大于30部门所有人的工资的员工
select * from emp where sal > all(select sal from emp where deptno=30);

-- 和李白岗位部门都相同的员工
select * from emp where (job, deptno) in (select jobm, deptno from emp where ename ='李白');

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

课时16 16.多表查询练习第1题

查询至少有一个员工的部门,显示部门编号,部门名称,部门位置,部门人数

-- 部门编号,部门名称,部门位置
select * from dept;

-- 部门人数
select deptno, count(*) from emp group by deptno

-- 整合
select d.* e1.cnt from dept d inner join 
(select deptno, count(*) cnt from emp group by deptno) as e1
on d.deptno=e1.deptno

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

课时17 17.多表查询练习第2题

列出所有员工的姓名及其直接上级的姓名

select e.ename, m.ename
from emp e left outer join emp m
on e.mgr=m.empno;

  
 
  • 1
  • 2
  • 3

课时18 18.多表查询练习第4题

列出受雇日期早于直接上级的所有员工编号,姓名,部门名称

-- 1、先查询员工
select e.empno, e.ename, e.deptno
from emp e, emp m
where e.mgr=m.empno and e.hiredate<m.hiredate

-- 2、查询部门名称
select e.empno, e.ename, d.dname
from emp e, emp m, dept d
where e.mgr=m.empno 
and e.hiredate<m.hiredate 
and e.deptno=d.deptno

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

课时19 19.多表查询练习第5题

列出部门名称和这些部门的员工信息,同时列出哪些没有员工的部门

select *
from emp e right outer join dept d
on e.deptno=d.deptno;

  
 
  • 1
  • 2
  • 3

课时20 20.多表查询练习第7题

列出最低薪金大于15000的各种工作及从事此工作的员工人数

select job, count(*)
from emp e
group by job
having min(sal) > 15000

  
 
  • 1
  • 2
  • 3
  • 4

课时21 21.多表查询练习第8题

列出在销售部工作的员工姓名,假定不知道销售部的部门编号

select ename
from emp e
where e.deptno = (select deptno from dept where dname='销售部')

  
 
  • 1
  • 2
  • 3

课时22 22.多表查询练习第9题

列出薪金高于公司平均薪金的所有员工信息,所在部门名称,上级领导,工资等级

-- 薪金高于公司平均薪金的所有员工信息
select * from emp where e.sal>(select avg(sal) from emp)

select e.*, d.dname, m.ename, s.grade 
from emp e left outer join dept d on e.deptno=d.deptno left outer join emp m on e.mgr=m.empno left outer join salgrade s on e.sal between s.losal and s.hisal
where e.sal>(select avg(sal) from emp)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

课时23 23.多表查询练习第10题

列出与庞统从事相同工作的所有员工及部门名称

select e.*, d.dname
from emp e left outer join dept d
on e.deptno=d.deptno
where e.job=(select job from emp where ename='庞统')


  
 
  • 1
  • 2
  • 3
  • 4
  • 5

课时24 24.多表查询练习第11题

列出薪金高于部门30工作的所有员工的薪金的员工姓名和薪金,部门名称

select e.ename, e.sal, d.dname
from ename e left outer join deptno d
on e.deptno=d.deptno
where e.sal>(select max(sal) from emp where deptno=30)


  
 
  • 1
  • 2
  • 3
  • 4
  • 5

课时25 24.多表查询练习第13题

查出年份,利润,年度增长比

select * from tb_year
year  zz
2000  100
2001  150
2002  250
2003  300

select y1.* ifnull(concat((y1.zz-y2.zz)/y2.zz * 100, '%'), '0%') 增长比
from tb_year y1 left outer join tb_year y2
on y1.year=y2.year+1

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

文章来源: pengshiyu.blog.csdn.net,作者:彭世瑜,版权归原作者所有,如需转载,请联系作者。

原文链接:pengshiyu.blog.csdn.net/article/details/104225503

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。