创建外键的第二种方式
创建两个表
CREATE table student( sid int PRIMARY key, sname VARCHAR(10) );
CREATE table score( sid int , score INT );给score添加外键
alter table score add constraint fk_student_score_sid foreign key(sid) references student(sid);删除外键(要使用约束的别名来删除 因为一个表中可以有多个外键 需要使用约束名字)
-- 注意:约束名(外键名)不能重复
alter table score drop foreign key fk_student_score_sid;
表与表之间的关系
多对多的关系: 利用第三张表来表示关系的 并且第三张表作为从表拥有其他两个主表的外键
看下面一个例子:
-- 学生表
CREATE TABLE stu( sid int PRIMARY key, sname VARCHAR(20) );
-- 老师表
create table tea( tid int primary key, tname varchar(20) );
-- 中间表建立关系
CREATE TABLE stu_tea ( sid int, tid int );
ALTER TABLE stu_tea add CONSTRAINT fk_stu_tea_sid FOREIGN KEY(sid) REFERENCES stu(sid); ALTER TABLE stu_tea add CONSTRAINT fk_tea_stu_tid FOREIGN KEY(tid) REFERENCES tea(tid);
一对一的关系(不常用 完全可以写成一张表)
如果考虑查询效率问题 可以对表进行拆分, 拆分有度)
多表查询
一合并查询
create table A( name varchar(10), score int );
create table B( name varchar(10), score int );
insert into A values('a',10),('b',20),('c',30); insert into B values('a',10),('b',20),('d',40);:UNION 取两个表的并集 (字段名 类型相同); UNION all 把两个表的数据合并到一起
SELECT * FROM A UNION all SELECT * FROM B;查询结果:
a 10 b 20 c 30 a 10 b 20 c 30 a 10 b 20 d 40 a 10 b 20 d 40
select * from a,b; select * from student,score;这样查询会产生笛卡尔积(会产生大量无效数据)
**去除错误数据(利用两张表的编号相同去除)
select * from student,score where student.stuid = score.stuid; select student.stuid,score.score from student,score where student.stuid = score.stuid;
另外为了方便书写可以给表起个别名
别名查询
select s.stuid,c.score from student s,score c where s.stuid = c.stuid;
三表合并查询
创建科目表 create table course( courseid int, cname VARCHAR(20) );查询学生 老师 科目
SELECT s.stuname, c.score, u.cname FROM student s, score c, course u WHERE s.stuid = c.stuid AND c.courseid = u.courseid;链接查询(多表查询) on加条件
-- 内连接查询(inner 可以省略)
SELECT * FROM student s INNER JOIN score c ON s.stuid = c.stuid; -- 三表内查询 SELECT * FROM student s INNER JOIN score c JOIN course u ON s.stuid = c.stuid AND c.courseid = u.courseid;查询表中80分以上的学生信息 (姓名 分数 科目)
-- 1 SELECT s.stuname, c.score, u.cname FROM student s INNER JOIN score c JOIN course u ON s.stuid = c.stuid AND c.courseid = u.courseid where c.score>80; -- 2 SELECT s.stuname, c.score, e.cname FROM student s JOIN score c ON s.stuid = c.stuid JOIN course e ON e.courseid = c.courseid WHERE c.score > 80;外链接 左外链接 右外链接 (outer可以省略)
左外链接以左边的表为主 会查出左边表单的所有数据
select * from score LEFT OUTER JOIN student on student.stuid = score.stuid;自然链接 关键词 nature join
自动匹配两个表中 相同字段的值;
要求字段名和类型相同
select * from student NATURAL JOIN score;
子查询 (嵌套查询)
-- 员工表 部门表测试 查询工资高于JONES的员工信息
SELECT * from emp WHERE sal >( select sal from emp where ename = 'jones');查询与SCOTT同一个部门的员工。
SELECT * from emp where deptno = ( SELECT deptno from emp WHERE ename = 'scott');
工资高于30号部门所有人的员工信息
SELECT * FROM emp WHERE sal > ( SELECT max(sal) FROM `emp` emp WHERE deptno = 30 );查询工作和工资与MARTIN(马丁)完全相同的员工信息
方式一 select * from emp where job=( select job from emp where ename='MARTIN') and sal=( select sal from emp where ename='MARTIN'); -- 方式二 SELECT * FROM emp where(job,sal)in( select job ,sal FROM emp where ename = 'MARTIN');有2个以上直接下属的员工信息
SELECT * FROM emp WHERE empno IN( select mgr from emp GROUP BY mgr HAVING COUNT(mgr)>=2);查询员工编号为7788的员工名称、员工工资、部门名称、部门地址
SELECT e.ename, e.sal, d.dname, d.loc FROM emp e INNER JOIN dept d ON e.deptno = d.deptno WHERE empno = 7788;求各个部门薪水最高的员工所有信息
select * from emp where (deptno,sal) in( select deptno,MAX(sal) from emp GROUP BY deptno);**把查询出来的结果当做一张表来查询
SELECT * FROM emp e1, ( SELECT deptno, MAX(sal) masl FROM emp GROUP BY deptno ) e2 WHERE e1.sal = e2.masl AND e1.deptno = e2.deptno;求7369员工编号、姓名、经理编号和经理姓名
-- 自连接查询 要查找的信息在一张表中 单一次查不出来 把自己这个表当成 两个表来链接查询
SELECT e.empno, e.ename, p.ename FROM emp e, emp p WHERE p.empno = 7369 AND e.empno = p.mgr;