一、外键约束

1、创建外键

---每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任----主表

CREATE TABLE ClassCharger(

id TINYINT PRIMARY KEY auto_increment,

name VARCHAR (20),

age INT ,

is_marriged boolean-- show create table ClassCharger: tinyint(1)

);

INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),

("丹丹",14,0),

("歪歪",22,0),

("姗姗",20,0),

("小雨",21,0);----子表

CREATE TABLE Student(

id INT PRIMARY KEY auto_increment,

name VARCHAR (20),

charger_id TINYINT,--切记:作为外键一定要和关联主键的数据类型保持一致--[ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)

) ENGINE=INNODB;

INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),

("alvin2",4),

("alvin3",1),

("alvin4",3),

("alvin5",1),

("alvin6",3),

("alvin7",2);

DELETE FROM ClassCharger WHERE name="冰冰";

INSERT student (name,charger_id) VALUES ("yuan",1);-- 删除居然成功,可是 alvin3显示还是有班主任id=1的冰冰的;-----------增加外键和删除外键---------ALTER TABLE student ADD CONSTRAINT abc

FOREIGN KEY(charger_id)

REFERENCES classcharger(id);

ALTER TABLE student DROP FOREIGN KEY abc;

2、 INNODB支持的ON语句

--外键约束对子表的含义: 如果在父表中找不到候选键,则不允许在子表上进行insert/update--外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对--应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的-- on update/on delete子句-----------------innodb支持的四种方式---------------------------------------

-----cascade方式 在父表上update/delete记录时,同步update/delete掉子表的匹配记录-----外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除--------FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)

ON DELETE CASCADE------set null方式 在父表上update/delete记录时,将子表上匹配记录的列设为null-- 要注意子表的外键列不能为not nullFOREIGN KEY (charger_id) REFERENCES ClassCharger(id)

ON DELETE SET NULL------Restrict方式 :拒绝对父表进行删除更新操作(了解)------No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键-- 进行update/delete操作(了解)

二、多表查询

--准备两张表--company.employee--company.department

create table employee(

emp_idint auto_increment primary key not null,

emp_name varchar(50),

ageint,

dept_idint);

insert into employee(emp_name,age,dept_id) values

('A',19,200),

('B',26,201),

('C',30,201),

('D',24,202),

('E',20,200),

('F',38,204);

create table department(

dept_idint,

dept_name varchar(100)

);

insert into department values

(200,'人事部'),

(201,'技术部'),

(202,'销售部'),

(203,'财政部');

mysql> select * fromemployee;+--------+----------+------+---------+

| emp_id | emp_name | age | dept_id |

+--------+----------+------+---------+

| 1 | A | 19 | 200 |

| 2 | B | 26 | 201 |

| 3 | C | 30 | 201 |

| 4 | D | 24 | 202 |

| 5 | E | 20 | 200 |

| 6 | F | 38 | 204 |

+--------+----------+------+---------+

6 rows in set (0.00sec)

mysql> select * fromdepartment;+---------+-----------+

| dept_id | dept_name |

+---------+-----------+

| 200 | 人事部 |

| 201 | 技术部 |

| 202 | 销售部 |

| 203 | 财政部 |

+---------+-----------+

4 rows in set (0.01 sec)

1、多表查询之连接查询

1.笛卡尔积查询

mysql> SELECT *FROM employee,department;-- selectemployee.emp_id,employee.emp_name,employee.age,-- department.dept_name fromemployee,department;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 1 | A | 19 | 200 | 201 | 技术部 |

| 1 | A | 19 | 200 | 202 | 销售部 |

| 1 | A | 19 | 200 | 203 | 财政部 |

| 2 | B | 26 | 201 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 2 | B | 26 | 201 | 202 | 销售部 |

| 2 | B | 26 | 201 | 203 | 财政部 |

| 3 | C | 30 | 201 | 200 | 人事部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 202 | 销售部 |

| 3 | C | 30 | 201 | 203 | 财政部 |

| 4 | D | 24 | 202 | 200 | 人事部 |

| 4 | D | 24 | 202 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 4 | D | 24 | 202 | 203 | 财政部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

| 5 | E | 20 | 200 | 201 | 技术部 |

| 5 | E | 20 | 200 | 202 | 销售部 |

| 5 | E | 20 | 200 | 203 | 财政部 |

| 6 | F | 38 | 204 | 200 | 人事部 |

| 6 | F | 38 | 204 | 201 | 技术部 |

| 6 | F | 38 | 204 | 202 | 销售部 |

| 6 | F | 38 | 204 | 203 | 财政部 |

+--------+----------+------+---------+---------+-----------+

2.内连接

--查询两张表中都有的关联数据,相当于利用条件从笛卡尔积结果中筛选出了正确的结果。select * from employee,department where employee.dept_id =department.dept_id;--select * from employee inner join department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

+--------+----------+------+---------+---------+-----------+

3.外连接

--(1)左外连接:在内连接的基础上增加左边有右边没有的结果select * from employee left join department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 6 | F | 38 | 204 | NULL | NULL |

+--------+----------+------+---------+---------+-----------+

--(2)右外连接:在内连接的基础上增加右边有左边没有的结果select * from employee RIGHT JOIN department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

| NULL | NULL | NULL | NULL | 203 | 财政部 |

+--------+----------+------+---------+---------+-----------+

--(3)全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果--mysql不支持全外连接 full JOIN--mysql可以使用此种方式间接实现全外连接select * from employee RIGHT JOIN department on employee.dept_id =department.dept_id

UNIONselect * from employee LEFT JOIN department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

| NULL | NULL | NULL | NULL | 203 | 财政部 |

| 6 | F | 38 | 204 | NULL | NULL |

+--------+----------+------+---------+---------+-----------+

-- 注意 union与union all的区别:union会去掉相同的纪录

2、多表查询之复合条件连接查询

--查询员工年龄大于等于25岁的部门

SELECT DISTINCT department.dept_name

FROM employee,department

WHERE employee.dept_id=department.dept_id

AND age>25;--以内连接的方式查询employee和department表,并且以age字段的升序方式显示selectemployee.emp_id,employee.emp_name,employee.age,department.dept_namefromemployee,departmentwhere employee.dept_id =department.dept_id

order by age asc;

3、多表查询之子查询

--子查询是将一个查询语句嵌套在另一个查询语句中。--内层查询语句的查询结果,可以为外层查询语句提供查询条件。--子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字-- 还可以包含比较运算符:= 、 !=、> 、

(select dept_id fromdepartment);+--------+----------+------+---------+

| emp_id | emp_name | age | dept_id |

+--------+----------+------+---------+

| 1 | A | 19 | 200 |

| 2 | B | 26 | 201 |

| 3 | C | 30 | 201 |

| 4 | D | 24 | 202 |

| 5 | E | 20 | 200 |

+--------+----------+------+---------+

5 rows in set (0.01sec)-- 2. 带比较运算符的子查询-- =、!=、>、>=、

--查询员工年龄大于等于25岁的部门select dept_id,dept_name fromdepartmentwheredept_id IN

(select DISTINCT dept_id from employee where age>=25);-- 3. 带EXISTS关键字的子查询--EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。--而是返回一个真假值。Ture或False--当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询select * fromemployee

WHERE EXISTS

(SELECT dept_namefrom department where dept_id=203);--department表中存在dept_id=203,Tureselect * fromemployee

WHERE EXISTS

(SELECT dept_namefrom department where dept_id=205);-- Empty set (0.00sec)

ps: create table t1(select * from t2);

三、课后练习

练习一:

1、将所有的课程的名称以及对应的任课老师姓名打印出来

SELECT cid,cname,tname FROM course LEFT JOIN teacher on course.teacher_id=teacher.tid;

2、查询学生表中男女生各有多少人

SELECT gender,COUNT(gender) 人数 FROM student GROUP BY gender;

3、查询物理成绩等于100的学生的姓名

SELECT sid,sname FROM student WHERE sid in (SELECT student_id FROM score WHERE course_id=(SELECT cid FROM course WHERE cname='物理') and num=100);

4、查询平均成绩大于八十分的同学的姓名和平均成绩

SELECT sname,AVG(num) FROM student,score WHERE student.sid=score.student_id GROUP BY student_id HAVING AVG(num)>80;

5、查询所有学生的学号,姓名,选课数,总成绩

SELECT student_id 学号 ,sname 姓名,COUNT(course_id) 选课数,SUM(num) 总成绩 FROM student,score WHERE student.sid=student_id GROUP BY student_id;

6、查询姓李老师的个数

SELECT COUNT(tname) 姓李老师个数 from teacher WHERE tname like '李%';

7、查询没有报李平老师课的学生姓名

SELECT sid,sname FROM student WHERE sid NOT IN (SELECT distinct student_id from score LEFT JOIN student on student_id=student.sid WHERE course_id in (SELECT cid from course,teacher WHERE teacher_id=tid and tname='李平老师'));

mysql> select sid,sname from student where sid not in (SELECT distinct student_id from score where course_id in (SELECT cid from course,teacher WHERE teacher_id=tid and tname='李平老师'));

8、查询物理课程比生物课程高的学生的学号

SELECT A.student_id FROM

(SELECT * FROM score WHERE course_id=(SELECT cid FROM course WHERE cname='物理'))A

INNER JOIN

(SELECT * FROM score WHERE course_id=(SELECT cid FROM course WHERE cname='生物')) B ON A.student_id = B.student_id WHERE A.num>B.num

9、查询没有同时选修物理课程和体育课程的学生姓名

SELECT sid,sname from student WHERE sid NOT IN (SELECT student_id from score WHERE course_id in (2,3) GROUP BY student_id HAVING COUNT(student_id)=2);

10、查询挂科超过两门(包括两门)的学生姓名和班级

SELECT sname,caption FROM student,class WHERE class_id=cid and sid IN (SELECT student_id FROM score WHERE num<60 GROUP BY student_id HAVING COUNT(student_id)>=2);

11 、查询选修了所有课程的学生姓名

SELECT sname FROM student WHERE sid in (SELECT student_id FROM score  GROUP BY student_id HAVING COUNT(course_id)=(SELECT COUNT(cid) FROM course));

12、查询李平老师教的课程的所有成绩记录

SELECT sid,sname,cname,num FROM  student RIGHT JOIN (SELECT student_id,cname,num FROM  score,course WHERE course_id=cid AND course_id in (SELECT cid from course,teacher WHERE teacher_id=tid and tname='李平老师')) ls on ls.student_id=student.sid;

13、查询选课学生都选修了的课程号和课程名

SELECT cid,cname FROM course WHERE cid =(SELECT course_id from score GROUP BY course_id HAVING COUNT(student_id)=(select count(distinct student_id) from score))

练习二:

14、查询每门课程被选修的次数

SELECT course_id,cname,COUNT(course_id) 被选课次数 FROM score,course WHERE cid=course_id GROUP BY course_id;

15、查询只选修了一门课程的学生姓名和学号

SELECT sid,sname FROM student WHERE sid =(SELECT student_id FROM score GROUP BY student_id HAVING COUNT(course_id)=1);

16、查询所有学生考出的成绩并按从高到低排序(成绩去重)

SELECT DISTINCT num FROM score ORDER BY num DESC;

17、查询平均成绩大于85的学生姓名和平均成绩

SELECT sname,AVG(num) FROM score,student WHERE student_id =student.sid GROUP BY student_id HAVING AVG(num)>85;

18、查询生物成绩不及格的学生姓名和对应生物分数

SELECT sname,num FROM score,student WHERE student_id=student.sid AND course_id=(SELECT cid FROM course WHERE cname='生物') and num<60;

19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名

SELECT student_id,sname,AVG(num) FROM score,student WHERE student_id=student.sid AND course_id in (SELECT cid FROM course WHERE teacher_id =( SELECT tid FROM teacher WHERE tname like '李平%')) GROUP BY student_id  ORDER BY AVG(num) DESC LIMIT 1;

20、查询每门课程成绩最好的前两名学生姓名

21、查询不同课程但成绩相同的学号,课程号,成绩

SELECT * FROM score WHERE student_id IN (SELECT student_id FROM score GROUP BY num,student_id HAVING COUNT(student_id)>=2);

22、查询没学过“李平”老师课程的学生姓名以及选修的课程名称;

SELECT * from score WHERE student_id NOT IN (select distinct student_id from score where course_id in (SELECT cid FROM

course WHERE teacher_id =( SELECT tid FROM teacher WHERE tname like '李平%')));

23、查询所有选修了学号为1的同学选修过的一门或者多门课程的同学学号和姓名;

SELECT sid,sname FROM student WHERE sid IN (SELECT DISTINCT student_id FROM score WHERE course_id IN (SELECT course_id from score WHERE student_id=1) AND student_id!=1);

24、任课最多的老师中学生单科成绩最高的学生姓名

SELECT sname FROM student WHERE sid IN (SELECT student_id FROM score,(SELECT course_id,MAX(num) 最大值 FROM score WHERE course_id in (SELECT cid FROM course WHERE teacher_id=(SELECT teacher_id FROM course GROUP BY teacher_id ORDER BY COUNT(cid) DESC LIMIT 1)) GROUP BY course_id HAVING max(num)) A WHERE A.最大值=score.num AND score.course_id=A.course_id);

mysql联表查询多记录显示_数据库:MySQL(多表的表记录的查询)(三)相关推荐

  1. mysql交叉表的构造知识_[数据库]MySQL交叉表

    [数据库]MySQL交叉表 0 2012-01-11 17:00:23 在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解决方法,特发贴集思广义. http:// ...

  2. mysql存储过程返回多个值_数据库mysql存储过程之返回多个值的方法示例

    本文实例讲述了mysql存储过程之返回多个值的方法.分享给大家供大家参考,具体如下: mysql存储函数只返回一个值.要开发返回多个值的存储过程,需要使用带有INOUT或OUT参数的存储过程.咱们先来 ...

  3. mysql以下日期函数正确的_[数据库]MYSQL基础03(日期函数)

    [数据库]MYSQL基础03(日期函数) 0 2015-10-29 01:00:09 工作中对日期的处理是经常遇到的,需求可能多种多样,因此重点介绍. 1.获取当前日期select NOW()-- 结 ...

  4. mysql查出倒序第一条数据_[数据库]mysql 记录根据日期字段倒序输出

    [数据库]mysql 记录根据日期字段倒序输出 0 2016-07-21 11:00:17 我们知道倒序输出是很简单的 select * from table order by id desc 直接这 ...

  5. mysql怎么将成绩划分等级_数据库mysql中case如何给成绩划分等级?

    在表格中如果我们要给不同分段的成绩评选等级,只需要使用筛选功能输入评定的条件即可.那么在mysql中我们该如何输出跟表格一样结果呢?这里有的小伙伴说可以用我们刚学习的case函数来尝试.但是作为最基础 ...

  6. mysql清空数据库所有表的命令_mysql清空表数据命令是什么?_数据库,mysql,清空表数据...

    mysql服务无法启动怎么解决_数据库 mysql服务无法启动的解决方法是:1.配置环境变量:2.在mysql安装目录下,新建my.ini文件,设置默认字符集.端口.存储引擎等:3.执行[mysqld ...

  7. mysql where 条件取反_数据库MySQL之where条件查询

    数据库MySQL之where条件查询 1. where条件查询的介绍 使用where条件查询可以对表中的数据进行筛选,条件成立的记录会出现在结果集中. where语句支持的运算符: 比较运算符 逻辑运 ...

  8. mysql 慢查询 不重启_开启mysql慢查询日志,不重启数据库的方法

    nagios监控到bbs的数据库,有几千条的慢查询纪录,而且在不断的上涨 Uptime: 2665801 Threads: 9 Questions: 1483924522 Slow queries: ...

  9. mysql 横纵表转化_数据库MySQL横纵表相互转化操作实现方法

    本文实例讲述了MySQL横纵表相互转化操作实现方法.分享给大家供大家参考,具体如下: 先创建一个成绩表(纵表) create table user_score ( name varchar(20), ...

最新文章

  1. NHibernate 基本配置 (第一篇)
  2. mysql-索引-笔记
  3. 一分钟检测应用状态 | 企业应用健康扫描中心发布
  4. 山东理工OJ【2121】数据结构实验之链表六:有序链表的建立(插排法)
  5. 蓝牙驱动卸载后自动安装_Intel 蓝牙驱动安装教程
  6. permission denied是什么鬼?
  7. mysql cleaned up_MySQL数据库无法启动的简单排错
  8. 要不要使用外键(foreign key )?
  9. Linux 抄袭 Unix ?今日终有定论!
  10. koreader下载_Koreader阅读器app免费安装最新版|Koreader阅读器2018手机最新版下载_v1.0_9ht安卓下载...
  11. 《Redis视频教程》(p5)
  12. facebook的network-connection-class(测量移动端网络质量)源码详解
  13. XML实现异构数据库间转换的实现与分析
  14. ubuntu 屏幕旋转与重力感应
  15. Android中使用Post带参数请求的方法
  16. ccc 邮箱_CCC的完整形式是什么?
  17. 5G移动通信系统设计与标准详解 个人整理(PDF和Word)
  18. 【算法和数据结构学习笔记】整合版
  19. H5页面是什么意思?H5游戏怎么做?
  20. 数学家的情书-笛卡尔的心型线方程

热门文章

  1. nginx在linux上安装,Nginx在linux上安装步骤
  2. 提高抗打击能力_输不起、爱放弃,孩子抗挫能力差怎么办?3招教你培养孩子抗挫力...
  3. 卧槽,B站联名键盘!
  4. 不好意思,我真的不知道MySQL的窗口函数...
  5. MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk.
  6. java基础之包装类
  7. asin c语言中 返回值范围_asin()_C语言asin()详解:反正弦函数,求反正弦值
  8. keep健身软件电脑版_一款不错的健身软件keep会员实现教程
  9. Centos7下关闭带验证的MongoDB
  10. POJ-2942:吃糖果