表关系
-
一对一(one to one) :每个实体的独有属性(区别于其他实体),如个人的邮箱,每个用户的邮箱都是不同的,即用户与邮箱之间的关系为一对一关系。用户与购物行为,因为多个用户都可以购物,则两者为多对一的关系。表与表之间有相同主键,即为一对一关系。
-
一对多(one to many):一个用户可以买多个商品,一个商品可以被多个用户购买,即多对多,需要一个用户表(主键:用户)和一个商品表(主键:不是用户),商品表的外键参考用户表的主键。
-
多对多(many to many):一个用户可以购买多个商品,一个商品可以被多个用户购买也可以被一个用户购买多次,这是就需要创建关联表,关联表是以两张表的主键建立,但是关联表的每列不需具有唯一性,类似于复合建,列合起来具有唯一性。
一对多 建表
员工表:emp
部门表:dept
create database day0902;
use day0902;
create table dept(
did int primary key,
dname varchar(20);
)
create table emp (
eid int primary key,
ename varchar(20),
eage int,
dept_did int,
sex varchar(10),
foreign key(dept_did) references dept(did)
)
1. 查询年纪最大的两个员工
select * from emp order by eage desc limit 0,2;
2. 查询年龄大于平均年龄的员工
select avg(eage) from emp ;//得到员工的平均年龄
select * from emp where eage > ( select avg(eage) from emp );
3. 查询年龄大于女员工平均年龄的男员工
select avg(eage) from emp where sex = "女";//得到女员工的平均年龄
select * from emp where sex = "男" and (eage > select avg(eage) from emp where sex = "女");
4. 查询每个部门年龄最大的员工
select e.ename, e.eage , t.dname from emp as e , (select max(eage) m ,dept_did dname from emp , dept where did = dept_did group by dname) as t where e.dept_did = t.dept_did and e.eage = t.m;
多对多 建表(两个表和一个中间表)
课程表:
create database day0903;
use day0903;
create table sub(
sid int primary key,
sname varchar(10)
);
学生表:
create table stu (
sid int primary key,
sname varchar(10),
sage int
);
中间表:
create table tb_stu_course(
stid int,
suid int,
foreign key(stid) references stu(sid),
foreign key(suid) references course(sid)
)
1. 查询没有选择课程的学生
select * from
( select * from stu left join tb_stu_sub ss on stu.sid = ss.stid and suid is null ) t where stid = null;
2. 查询选择人数最少的课程
select * from(
select count(sname) c, sname from sub, tb_stu_sub ss where sub.sid = ss.suid group by sname) tb1 where c = (select min(c) from (select count(sname) c, sname from sub, tb_stu_sub ss where sub.sid = ss.suid group by sname) tb2);
3. 查询同时选了语文和数学的人
select a, count(b) c from (
select stu.sname a , sub.sname b from stu , tb_stu_sub ss , sub
where stu.sid = ss.stid and sub.sid = ss.suid and (sub.sname = "语文" or sub.sname = "数学")) tb1 group by a ) tb2 where c = 2;
);
4. 查询学生平均年龄最小的课程
select b , avg(age) av from (
select stu.sname a , stu.sage age , sub.sname b from stu , tb_stu_sub ss , sub
where stu.sid = ss.stid and sub . sid = ss.suid ) tb1
group by b order by av limit 0 , 1;
);