MySQL数据库练习

1.1  SQL语句的多表操作:

1.1.1    多表的设计:

一对多:

* 一对多:

* 一个部门有多个员工,一个员工只能属于某一个部门.

* 一个用户产生多个订单,一个订单只能属于某一个用户.

 

* 创建表:

create database web016;

use web016;

create table dept(

did int primary keyauto_increment,

dname varchar(20)

);

 

create table employee(

eid int primary keyauto_increment,

ename varchar(20),

sex varchar(20),

age int,

dno int

);

 

insert into dept values (null,'市场部');

insert into dept values (null,'研发部');

insert into dept values (null,'人事部');

 

insert into employee values (null,'张三','男',23,1);

insert into employee values (null,'李四','男',28,1);

insert into employee values (null,'王五','女',25,3);

insert into employee values (null,'赵六','女',31,2);

insert into employee values (null,'孙七','男',22,3);

 

假设需要删除市场部!市场部对应的员工应该如何进行处理?

多表之间约束:(约束:保证数据的完整性)

外键约束:

* alter table employee add foreign key(dno)references dept(did);

 

***** 一对多的建表原则:

在多的一方创建一个字段,作为外键指向一的一方的主键.

多对多:

* 多对多:

* 一个学生可以选择多门课程,一门课程可以被多个学生所选择.

* 一个角色可以有多个权限,一个权限也可以属于多个角色.

 

创建表:

create table student(

sid intprimary key auto_increment,

snamevarchar(20)

);

 

create table course(

cid intprimary key auto_increment,

cnamevarchar(20)

);

 

insert into student values (null,'张三');

insert into student values (null,'李四');

insert into student values (null,'王五');

 

insert into course values (null,'Java');

insert into course values (null,'PHP');

insert into course values (null,'IOS');

insert into course values (null,'C++');

 

create table stu_cour(

sno int, 

cno int

);

alter table stu_cour add foreign key(sno)references student(sid);

alter table stu_cour add foreign key(cno)references course(cid);

insert into stu_cour values (1,1);

insert into stu_cour values (1,2);

insert into stu_cour values (1,3);

insert into stu_cour values (2,2);

insert into stu_cour values (2,4);

insert into stu_cour values (3,3);

***** 多对多建表原则:

创建一个中间表:(第三张表),中间表中需要有两个字段.分别作为外键指向多对多双方的主键.

一对一:

* 一对一:

* 一个公司对应一个注册地址.同时一个注册地址只能被一个公司注册.

* 实际开发中一对一的关系并不是很常用.

 

* 一对一的建表原则:

* 唯一外键对应:

* 假设一对一的双方任意一方是多.(假设为一对多).需要在多的一方创建外键指向一的一方的主键.但同时将这个外键设置为唯一的unique.

* 主键对应:
                * 在任意的一方的主键上添加一个外键约束.指向另一方的主键.

 购物网站的建表分析:

 

1.2  SQL的多表查询:

1.2.1    多表的查询:

笛卡尔积查询:(交叉连接查询)

* 交叉连接:

* 语法:

* select * from A,B;

 

* 两个表的交叉连接:得到的记录是两个表的笛卡尔积.

 

内连接查:经常使用.

* 内连接:inner join.

* 内连接查询的结果:实质上是两个表的交集.

* 语法:

* select * from A inner joinon 条件;(inner 可以省略)

* 隐式内连接:

* select * from A,B where 条件;

* 显式内连接:

* select * from A inner join B on 条件;

 

练习:

* SELECT * FROM dept d INNER JOIN employee e  ON d.did = e.dno;    ---显式内连接.

* SELECT * FROM dept d,employee e WHERE d.did = e.dno;             ---隐式内连接.

外连接查询:

* 外连接:outer join

* 左外连接:

* 查询的结果:是左边表的全部以及两个表的交集.

* 语法:

* select * from A left outer joinon 条件;

 

* 右外连接:

* 查询的结果:是右边表的全部以及两个表的交集.

* 语法:

* select * from A right outer joinon 条件;

 

练习:

* SELECT * FROM dept d LEFT OUTER JOIN employee e ON d.did = e.dno;

* SELECT * FROM dept d RIGHT OUTER JOIN employee e ON d.did = e.dno;

1.2.2    子查询:

什么是子查询:

子查询:指的是一条语句的查询结果需要依赖另一条语句的查询结果.

 

案例:

* 查询员工年龄大于平均年龄的员工的信息.

* 求平均年龄:

* select avg(age) from employee;

* 求员工年龄大于平均值:

* select * from employee where age > 平均值.

* 完整语句:

* select * from employee where age > (select avg(age) fromemployee);

 

在子查询中使用的关键字:any、all.

* any:任意一个.

* all:所有.

 

* any:

案例:

* 查询员工的年龄大于任意一部门员工的年龄.

* 分析:

* 查询一号部门的员工的年龄.

* select age from employee where dno = 1;

* any代表就是任意:

* select * from employee where age > any (select age fromemployee where dno = 1);

* 查询员工的年龄小于任意一部门员工的年龄.

* 分析:

* 查询一号部门的员工的年龄.

* select age from employee where dno = 1;

* any代表任意:

* select * from employee where age < any (select age fromemployee where dno = 1);

 

* all:所有:

* 案例:

* 查询员工的年龄大于所有一部门的员工的年龄.

* 分析:

* 查询一号部门的员工的年龄.

* select age from employee where dno = 1;

* all代表就是所有:

* select * from employee where age > all (select age fromemployee where dno = 1);

* 查询员工的年龄小于所有一部门的员工的年龄.

分析:

* 查询一号部门的员工的年龄.

* select age from employee where dno = 1;

* all代表就是所有:

* select * from employee where age < all (select age fromemployee where dno = 1);

1.2.3    多表查询的练习:

练习:

* 按照部门名称统计每个部门的员工的个数.

* 统计个数:selectcount(*) from employee;

* 分组统计: group by.

* 按照部门的编号统计员工的个数:selectdno ,count(*) from employee group by dno;

* 如果按照名称统计,名称没有在员工表中,需要查询部门表.

select d.dname,count(*) from dept d,employee e where d.did =e.dno group by d.dname;

 

* 按照部门名称统计每个部门的员工的平均年龄.

* select d.dname,avg(age) from dept d,employee e where d.did = e.dnogroup by d.dname;

 

* 查询哪些员工的年龄大于任意部门的平均年龄.

* 查询每个部门的平均年龄.

* select avg(age) from dept d,employee e where d.did = e.dno groupby d.dname;

* 完整的语句:

* select * from employee where age > any (select avg(age) fromdept d,employee e where d.did = e.dno group by d.dname);

* 查询哪些员工的年龄大于等于所有部门的平均年龄.

* 完整的语句:

* select * from employee where age >= all(select avg(age) fromdept d,employee e where d.did = e.dno group by d.dname);

 

* 查询姓名为张三的学生选择了哪几门课程的名称.

* 查询每个学生选择的课程

* select * from student s,stu_cour sc,course c where s.sid = sc.snoand sc.cno = c.cid;

* 查询姓名为张三:

* SELECT c.cname FROM student s,stu_cour sc,course c WHERE s.sid =sc.sno AND sc.cno = c.cid AND s.sname='张三';

 

* 查询课程名称为Java的课程被哪些学生选择.

* select s.sname from student s,stu_cour sc,course c WHERE s.sid =sc.sno AND sc.cno = c.cid and c.cname = 'Java';

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值