petset mysql伸缩_20000字干货笔记,一天搞定Mysql~

SELECT s_no, c_no, degree FROM score;+------+-------+--------+| s_no |c_no | degree |+------+-------+--------+| 103 |3- 105| 92 || 103 |3- 245| 86 || 103 |6- 166| 85 || 105 |3- 105| 88 || 105 |3- 245| 75 || 105 |6- 166| 79 || 109 |3- 105| 76 || 109 |3- 245| 68 || 109 |6- 166| 81 |+------+-------+--------+

通过分析可以发现,只要把score表中的s_no字段值替换成student表中对应的name字段值就可以了,如何做呢?

-- FROM...: 表示从 student, score 表中查询-- WHERE 的条件表示为,只有在 student.no 和 score.s_no 相等时才显示出来。SELECT name, c_no, degree FROM student, scoreWHERE student.no = score.s_no;+-----------+-------+--------+| name |c_no | degree |+-----------+-------+--------+| 王丽 |3- 105| 92 || 王丽 |3- 245| 86 || 王丽 |6- 166| 85 || 王芳 |3- 105| 88 || 王芳 |3- 245| 75 || 王芳 |6- 166| 79 || 赵铁柱 |3- 105| 76 || 赵铁柱 |3- 245| 68 || 赵铁柱 |6- 166| 81 |+-----------+-------+--------+

多表查询 - 2

查询所有学生的no、课程名称 (course表中的name) 和成绩 (score表中的degree) 列。

只有score关联学生的no,因此只要查询score表,就能找出所有和学生相关的no和degree:

SELECT s_no, c_no, degree FROM score;+------+-------+--------+| s_no |c_no | degree |+------+-------+--------+| 103 |3- 105| 92 || 103 |3- 245| 86 || 103 |6- 166| 85 || 105 |3- 105| 88 || 105 |3- 245| 75 || 105 |6- 166| 79 || 109 |3- 105| 76 || 109 |3- 245| 68 || 109 |6- 166| 81 |+------+-------+--------+

然后查询course表:

SELECTno, nameFROMcourse;+ -------+-----------------+| no | name |+ -------+-----------------+| 3-105 | 计算机导论 || 3-245 | 操作系统 || 6-166 | 数字电路 || 9-888 | 高等数学 |+ -------+-----------------+

只要把score表中的c_no替换成course表中对应的name字段值就可以了。

-- 增加一个查询字段 name,分别从 score、course 这两个表中查询。-- as 表示取一个该字段的别名。SELECT s_no, name as c_name, degree FROM score, courseWHERE score.c_no = course.no;+------+-----------------+--------+| s_no |c_name | degree |+------+-----------------+--------+| 103 |计算机导论 | 92 || 105 |计算机导论 | 88 || 109 |计算机导论 | 76 || 103 |操作系统 | 86 || 105 |操作系统 | 75 || 109 |操作系统 | 68 || 103 |数字电路 | 85 || 105 |数字电路 | 79 || 109 |数字电路 | 81 |+------+-----------------+--------+

三表关联查询

查询所有学生的name、课程名 (course表中的name) 和degree。

只有score表中关联学生的学号和课堂号,我们只要围绕着score这张表查询就好了。

SELECT * FROM score;+------+-------+--------+| s_no |c_no | degree |+------+-------+--------+| 103 |3- 105| 92 || 103 |3- 245| 86 || 103 |6- 166| 85 || 105 |3- 105| 88 || 105 |3- 245| 75 || 105 |6- 166| 79 || 109 |3- 105| 76 || 109 |3- 245| 68 || 109 |6- 166| 81 |+------+-------+--------+

只要把 s_no 和 c_no 替换成 student 和 course 表中对应的 name 字段值就好了。

首先把 s_no 替换成 student 表中的 name 字段:

SELECT name, c_no, degree FROM student, score WHERE student.no = score.s_no;+-----------+-------+--------+| name |c_no | degree |+-----------+-------+--------+| 王丽 |3- 105| 92 || 王丽 |3- 245| 86 || 王丽 |6- 166| 85 || 王芳 |3- 105| 88 || 王芳 |3- 245| 75 || 王芳 |6- 166| 79 || 赵铁柱 |3- 105| 76 || 赵铁柱 |3- 245| 68 || 赵铁柱 |6- 166| 81 |+-----------+-------+--------+

再把c_no替换成course表中的name字段:

-- 课程表SELECTno, nameFROMcourse;+ -------+-----------------+| no | name |+ -------+-----------------+| 3-105 | 计算机导论 || 3-245 | 操作系统 || 6-166 | 数字电路 || 9-888 | 高等数学 |+ -------+-----------------+-- 由于字段名存在重复,使用 "表名.字段名 as 别名" 代替。SELECTstudent.name ass_name, course.name asc_name, degreeFROMstudent, score, courseWHEREstudent.NO = score.s_noANDscore.c_no = course.no;

子查询加分组求平均分

查询95031 班学生每门课程的平均成绩。

在score表中根据student表的学生编号筛选出学生的课堂号和成绩:

-- IN (..): 将筛选出的学生号当做 s_no 的条件查询SELECTs_no, c_no, degree FROMscoreWHEREs_no IN( SELECTnoFROMstudent WHEREclass= '95031');+ ------+-------+--------+| s_no | c_no | degree |+ ------+-------+--------+| 105 | 3-105 | 88 || 105 | 3-245 | 75 || 105 | 6-166 | 79 || 109 | 3-105 | 76 || 109 | 3-245 | 68 || 109 | 6-166 | 81 |+ ------+-------+--------+

这时只要将c_no分组一下就能得出95031班学生每门课的平均成绩:

SELECTc_no, AVG(degree) FROMscoreWHEREs_no IN( SELECTnoFROMstudent WHEREclass= '95031')GROUPBYc_no;+ -------+-------------+| c_no | AVG(degree) |+ -------+-------------+| 3-105 | 82.0000 || 3-245 | 71.5000 || 6-166 | 80.0000 |+ -------+-------------+

子查询 - 1

查询在3-105课程中,所有成绩高于109号同学的记录。

先用子查询查找出109同学在3-105中的成绩

select* fromscorewherec_no = '3-105'ands_no= '109'

然后再以课程3-105为条件,查找成绩大76的记录

select* fromscorewherec_no = '3-105'anddegree>( selectdegree fromscorewherec_no = '3-105'ands_no= '109');

子查询 - 2

查询所有成绩高于109号同学的3-105课程成绩记录。

-- 不限制课程号,只要成绩大于109号同学的3-105课程成绩就可以。SELECT* FROMscoreWHEREdegree > ( SELECTdegree FROMscore WHEREs_no = '109'ANDc_no = '3-105');

YEAR 函数与带 IN 关键字查询

查询所有和 101、 108号学生同年出生的 no、 name、 birthday列。

selectno, name, birthday fromstudentwhereyear(birthday) in(selectyear(birthday) fromstudentwherenoin( 101, 108));

多层嵌套子查询

查询'张旭'教师任课的学生成绩表。

用的三张表teacher、course、score,首先找到教师编号:

SELECTNOFROMteacher WHERENAME= '张旭'

通过sourse表找到该教师课程号:

selectnofromcoursewheret_no = ( SELECTNOFROMteacher WHERENAME= '张旭')

通过筛选出的课程号查询成绩表:

select* fromscore wherec_no = (selectnofromcourse wheret_no = (selectnofromteacherwherename= '张旭'));

多表查询

查询某选修课程多于5个同学的教师姓名。

首先在teacher表中,根据no字段来判断该教师的同一门课程是否有至少5名学员选修:

-- 查询 teacher 表SELECTno, nameFROMteacher;+ -----+--------+| no | name |+ -----+--------+| 804 | 李诚 || 825 | 王萍 || 831 | 刘冰 || 856 | 张旭 |+ -----+--------+SELECTnameFROMteacher WHEREnoIN(-- 在这里找到对应的条件);

查看和教师编号有有关的表的信息:

SELECT * FROM course;-- t_no:教师编号+-------+-----------------+------+| no |name | t_no |+-------+-----------------+------+| 3-105 |计算机导论 | 825 || 3-245 |操作系统 | 804 || 6-166 |数字电路 | 856 || 9-888 |高等数学 | 831 |+-------+-----------------+------+

我们已经找到和教师编号有关的字段就在course表中,但是还无法知道哪门课程至少有5名学生选修,所以还需要根据score表来查询:

-- 在此之前向 score 插入一些数据,以便丰富查询条件。INSERTINTOscore VALUES( '101', '3-105', '90');INSERTINTOscore VALUES( '102', '3-105', '91');INSERTINTOscore VALUES( '104', '3-105', '89');-- 查询 score 表SELECT* FROMscore;+ ------+-------+--------+| s_no | c_no | degree |+ ------+-------+--------+| 101 | 3-105 | 90 || 102 | 3-105 | 91 || 103 | 3-105 | 92 || 103 | 3-245 | 86 || 103 | 6-166 | 85 || 104 | 3-105 | 89 || 105 | 3-105 | 88 || 105 | 3-245 | 75 || 105 | 6-166 | 79 || 109 | 3-105 | 76 || 109 | 3-245 | 68 || 109 | 6-166 | 81 |+ ------+-------+--------+

-- 在 score 表中将 c_no 作为分组,并且限制 c_no 持有至少 5 条数据。SELECTc_no FROMscore GROUPBYc_no HAVINGCOUNT(*) > 5;+ -------+| c_no |+ -------+| 3-105 |+ -------+

根据筛选出来的课程号,找出在某课程中,拥有至少5名学员的教师编号:

SELECTt_no FROMcourse WHEREnoIN(SELECTc_no FROMscore GROUPBYc_no HAVINGCOUNT(*) > 5);+ ------+| t_no |+ ------+| 825 |+ ------+在teacher表中,根据筛选出来的教师编号找到教师姓名:SELECT name FROM teacher WHERE no IN (-- 最终条件SELECTt_no FROMcourse WHEREnoIN(SELECTc_no FROMscore GROUPBYc_no HAVINGCOUNT(*) > 5));

子查询 - 3

查询 “计算机系” 课程的成绩表。

思路是,先找出teacher表中所有计算机系课程的编号,根据这个编号查询course表中的课程编号,再用课程编号查找score表

-- 通过 teacher 表查询所有 `计算机系` 的教师编号SELECTno, name, department FROMteacher WHEREdepartment = '计算机系'+ -----+--------+--------------+| no| name| department |+ -----+--------+--------------+| 804| 李诚 | 计算机系 || 825| 王萍 | 计算机系 |+ -----+--------+--------------+-- 通过 course 表查询该教师的课程编号SELECTnoFROMcourse WHEREt_no IN(SELECTnoFROMteacher WHEREdepartment = '计算机系');+ -------+| no |+ -------+| 3-245 || 3-105 |+ -------+

-- 根据筛选出来的课程号查询成绩表SELECT* FROMscore WHEREc_no IN(SELECTnoFROMcourse WHEREt_no IN(SELECTnoFROMteacher WHEREdepartment = '计算机系'));+ ------+-------+--------+| s_no | c_no | degree |+ ------+-------+--------+| 103 | 3-245 | 86 || 105 | 3-245 | 75 || 109 | 3-245 | 68 || 101 | 3-105 | 90 || 102 | 3-105 | 91 || 103 | 3-105 | 92 || 104 | 3-105 | 89 || 105 | 3-105 | 88 || 109 | 3-105 | 76 |+ ------+-------+--------+

UNION 和 NOT IN 的使用

查询计算机系 与 电子工程系 中的不同职称的教师。

+ -----+------+-----+------------+------------+------------+| no | name | sex | birthday | profession | department |+ -----+------+-----+------------+------------+------------+| 804 | 李诚 | 男 | 1958-12-02 | 副教授 | 计算机系 || 825 | 王萍 | 女 | 1972-05-05 | 助教 | 计算机系 || 831 | 刘冰 | 女 | 1977-08-14 | 助教 | 电子工程系 || 856 | 张旭 | 男 | 1969-03-12 | 讲师 | 电子工程系 |+ -----+------+-----+------------+------------+------------+-- NOT: 代表逻辑非SELECT* FROMteacher WHEREdepartment = '计算机系'ANDprofession NOTIN(SELECTprofession FROMteacher WHEREdepartment = '电子工程系')-- 合并两个集UNIONSELECT* FROMteacher WHEREdepartment = '电子工程系'ANDprofession NOTIN(SELECTprofession FROMteacher WHEREdepartment = '计算机系');

ANY 表示至少一个 - DESC ( 降序 )

查询课程3-105且成绩 至少 高于3-245的score表。

SELECT * FROM score WHERE c_no = '3-105';+------+-------+--------+| s_no |c_no | degree |+------+-------+--------+| 101 |3- 105| 90 || 102 |3- 105| 91 || 103 |3- 105| 92 || 104 |3- 105| 89 || 105 |3- 105| 88 || 109 |3- 105| 76 |+------+-------+--------+SELECT * FROM score WHERE c_no = '3-245';+------+-------+--------+| s_no |c_no | degree |+------+-------+--------+| 103 |3- 245| 86 || 105 |3- 245| 75 || 109 |3- 245| 68 |+------+-------+--------+

-- ANY:符合SQL语句中的任意条件。-- 也就是说,在 3- 105成绩中,只要有一个大于从 3- 245筛选出来的任意行就符合条件,-- 最后根据降序查询结果。SELECT * FROM score WHERE c_no = '3-105'AND degree > ANY(SELECT degree FROM score WHERE c_no = '3-245') ORDER BY degree DESC;+------+-------+--------+| s_no |c_no | degree |+------+-------+--------+| 103 |3- 105| 92 || 102 |3- 105| 91 || 101 |3- 105| 90 || 104 |3- 105| 89 || 105 |3- 105| 88 || 109 |3- 105| 76 |+------+-------+--------+

表示所有的 ALL

查询课程3-105且成绩高于3-245的score表。

-- 只需对上一道题稍作修改。-- ALL: 符合SQL语句中的所有条件。-- 也就是说,在 3-105 每一行成绩中,都要大于从 3-245 筛选出来全部行才算符合条件。SELECT* FROMscore WHEREc_no = '3-105'ANDdegree > ALL(SELECTdegree FROMscore WHEREc_no = '3-245');+ ------+-------+--------+| s_no | c_no | degree |+ ------+-------+--------+| 101 | 3-105 | 90 || 102 | 3-105 | 91 || 103 | 3-105 | 92 || 104 | 3-105 | 89 || 105 | 3-105 | 88 |+ ------+-------+--------+

复制表的数据作为条件查询

查询某课程成绩比该课程平均成绩低的score 表。

-- 查询平均分SELECT c_no, AVG(degree) FROM score GROUP BY c_no;b表+-------+-------------+| c_no |AVG(degree) |+-------+-------------+|3- 105| 87.6667 || 3-245 |76.3333||6- 166| 81.6667 |+-------+-------------+-- 查询 score 表select * from score;a表+------+-------+--------+| s_no |c_no | degree |+------+-------+--------+| 101 |3- 105| 90 || 102 |3- 105| 91 || 103 |3- 105| 92 || 103 |3- 245| 86 || 103 |6- 166| 85 || 104 |3- 105| 89 || 105 |3- 105| 88 || 105 |3- 245| 75 || 105 |6- 166| 79 || 109 |3- 105| 76 || 109 |3- 245| 68 || 109 |6- 166| 81 |+------+-------+--------+

-- 将表 b 作用于表 a 中查询数据-- score a (b): 将表声明为 a (b),-- 如此就能用 a.c_no = b.c_no 作为条件执行查询了。SELECT * FROM score a WHERE degree < ((SELECT AVG(degree) FROM score b WHERE a.c_no = b.c_no));+------+-------+--------+| s_no |c_no | degree |+------+-------+--------+| 105 |3- 245| 75 || 105 |6- 166| 79 || 109 |3- 105| 76 || 109 |3- 245| 68 || 109 |6- 166| 81 |+------+-------+--------+

子查询 - 4

查询所有任课 ( 在course表里有课程 ) 教师的name和department。

SELECTname, department FROMteacher WHEREnoIN( SELECTt_no FROMcourse);+ --------+-----------------+| name | department |+ --------+-----------------+| 李诚 | 计算机系 || 王萍 | 计算机系 || 刘冰 | 电子工程系 || 张旭 | 电子工程系 |+ --------+-----------------+

条件加组筛选

查询student表中至少有 2 名男生的class。

-- 查看学生表信息SELECT* FROMstudent;+ -----+-----------+-----+------------+-------+| no | name | sex | birthday | class |+ -----+-----------+-----+------------+-------+| 101 | 曾华 | 男 | 1977-09-01 | 95033 || 102 | 匡明 | 男 | 1975-10-02 | 95031 || 103 | 王丽 | 女 | 1976-01-23 | 95033 || 104 | 李军 | 男 | 1976-02-20 | 95033 || 105 | 王芳 | 女 | 1975-02-10 | 95031 || 106 | 陆军 | 男 | 1974-06-03 | 95031 || 107 | 王尼玛 | 男 | 1976-02-20 | 95033 || 108 | 张全蛋 | 男 | 1975-02-10 | 95031 || 109 | 赵铁柱 | 男 | 1974-06-03 | 95031 || 110 | 张飞 | 男 | 1974-06-03 | 95038 |+ -----+-----------+-----+------------+-------+-- 只查询性别为男,然后按 class 分组,并限制 class 行大于 1。select* fromstudent wheresex= '男'groupbyclasshavingcount( class)>= 2;+ -----+------+-----+------------+-------+| no| name| sex | birthday | class|+ -----+------+-----+------------+-------+| 101| 曾华 | 男 | 1977-09-01| 95033|| 102| 匡明 | 男 | 1975-10-02| 95031|+ -----+------+-----+------------+-------+

NOT LIKE 模糊查询取反

查询student 表中不姓 "王" 的同学记录。

-- NOT:取反-- LIKE:模糊查询mysql> SELECT * FROM student WHERE name NOT LIKE '王%';+-----+-----------+-----+------------+-------+| no |name | sex |birthday | class|+-----+-----------+-----+------------+-------+| 101 |曾华 | 男 |1977-09- 01| 95033 || 102 |匡明 | 男 |1975- 10- 02| 95031 || 104 |李军 | 男 |1976- 02- 20| 95033 || 106 |陆军 | 男 |1974- 06- 03| 95031 || 108 |张全蛋 | 男 |1975- 02- 10| 95031 || 109 |赵铁柱 | 男 |1974- 06- 03| 95031 || 110 |张飞 | 男 |1974- 06- 03| 95038 |+-----+-----------+-----+------------+-------+

YEAR 与 NOW 函数

查询student表中每个学生的姓名和年龄。

select name, year(now)-year(birthday) as agefrom student;+-----------+------+| name |age |+-----------+------+|曾华 | 42 || 匡明 |44||王丽 | 43 || 李军 |43||王芳 | 44 || 陆军 |45||王尼玛 | 43 || 张全蛋 |44||赵铁柱 | 45 || 张飞 |45|+-----------+------+

MAX 与 MIN 函数

查询student表中最大和最小的birthday值。

SELECTMAX(birthday), MIN(birthday) FROMstudent;+ ---------------+---------------+| MAX(birthday) | MIN(birthday) |+ ---------------+---------------+| 1977-09-01 | 1974-06-03 |+ ---------------+---------------+

多段排序

以class和birthday从大到小的顺序查询student表。

SELECT * FROM student ORDER BY classDESC, birthdayDESC;+-----+--------+-----+------------+-------+| no |name | sex |birthday | class|+-----+--------+-----+------------+-------+| 110 |张飞 | 男 |1974- 06- 03| 95038 || 101 |曾华 | 男 |1977-09- 01| 95033 || 104 |李军 | 男 |1976- 02- 20| 95033 || 107 |王尼玛 | 男 |1976- 02- 20| 95033 || 103 |王丽 | 女 |1976- 01- 23| 95033 || 102 |匡明 | 男 |1975- 10- 02| 95031 || 105 |王芳 | 女 |1975- 02- 10| 95031 || 108 |张全蛋 | 男 |1975- 02- 10| 95031 || 106 |陆军 | 男 |1974- 06- 03| 95031 || 109 |赵铁柱 | 男 |1974- 06- 03| 95031 |+-----+--------+-----+------------+-------+

子查询 - 5

查询 "男" 教师及其所上的课程。

SELECT* FROMcourse WHEREt_no in( SELECTnoFROMteacher WHEREsex = '男');+ -------+--------------+------+| no | name | t_no |+ -------+--------------+------+| 3-245 | 操作系统 | 804 || 6-166 | 数字电路 | 856 |+ -------+--------------+------+

MAX 函数与子查询

查询最高分同学的score表。

-- 找出最高成绩(该查询只能有一个结果)SELECTMAX(degree) FROMscore;-- 根据上面的条件筛选出所有最高成绩表,-- 该查询可能有多个结果,假设 degree 值多次符合条件。SELECT* FROMscore WHEREdegree = ( SELECTMAX(degree) FROMscore);+ ------+-------+--------+| s_no | c_no | degree |+ ------+-------+--------+| 103 | 3-105 | 92 |+ ------+-------+--------+

子查询 - 6

查询和 "李军" 同性别的所有同学name。

selectnamefromstudent wheresex = (SELECTsex FROMstudent wherename= '李军');+ --------+| name |+ --------+| 曾华 || 匡明 || 李军 || 陆军 || 王尼玛 || 张全蛋 || 赵铁柱 || 张飞 |+ --------+

子查询 - 7

查询和 "李军" 同性别且同班的同学name。

SELECTname, sex, classFROMstudent WHEREsex = (SELECTsex FROMstudent WHEREname= '李军') ANDclass= (SELECTclassFROMstudent WHEREname= '李军');+ -----------+-----+-------+| name | sex | class |+ -----------+-----+-------+| 曾华 | 男 | 95033 || 李军 | 男 | 95033 || 王尼玛 | 男 | 95033 |+ -----------+-----+-------+

子查询 - 8

查询所有选修 "计算机导论" 课程的 "男" 同学成绩表。

需要的 "计算机导论" 和性别为 "男" 的编号可以在course和student表中找到。

SELECT* FROMscore WHEREc_no = (SELECTnoFROMcourse WHEREname= '计算机导论') ANDs_no IN(SELECTnoFROMstudent WHEREsex = '男');+ ------+-------+--------+| s_no | c_no | degree |+ ------+-------+--------+| 101 | 3-105 | 90 || 102 | 3-105 | 91 || 104 | 3-105 | 89 || 109 | 3-105 | 76 |+ ------+-------+--------+

按等级查询

建立一个grade表代表学生的成绩等级,并插入数据:

CREATETABLEgrade (lowINT( 3),upp INT( 3),grade char( 1));INSERTINTOgrade VALUES( 90, 100, 'A');INSERTINTOgrade VALUES( 80, 89, 'B');INSERTINTOgrade VALUES( 70, 79, 'C');INSERTINTOgrade VALUES( 60, 69, 'D');INSERTINTOgrade VALUES( 0, 59, 'E');

SELECT* FROMgrade;+ ------+------+-------+| low | upp | grade |+ ------+------+-------+| 90 | 100 | A || 80 | 89 | B || 70 | 79 | C || 60 | 69 | D || 0 | 59 | E |+ ------+------+-------+

查询所有学生的 s_no 、 c_no 和 grade 列。

思路是,使用区间 (BETWEEN) 查询,判断学生的成绩 (degree) 在grade表的low和upp之间。

SELECT s_no, c_no, grade FROM score, gradeWHERE degree BETWEEN low AND upp;+------+-------+-------+| s_no |c_no | grade |+------+-------+-------+| 101 |3- 105| A || 102 |3- 105| A || 103 |3- 105| A || 103 |3- 245| B || 103 |6- 166| B || 104 |3- 105| B || 105 |3- 105| B || 105 |3- 245| C || 105 |6- 166| C || 109 |3- 105| C || 109 |3- 245| D || 109 |6- 166| B |+------+-------+-------+

连接查询

准备用于测试连接查询的数据:

CREATEDATABASEtestJoin;CREATETABLEperson (idINT,nameVARCHAR( 20),cardId INT);

CREATETABLEcard (idINT,nameVARCHAR( 20));

INSERTINTOcard VALUES( 1, '饭卡'), ( 2, '建行卡'), ( 3, '农行卡'), ( 4, '工商卡'), ( 5, '邮政卡');SELECT* FROMcard;+ ------+-----------+| id | name |+ ------+-----------+| 1 | 饭卡 || 2 | 建行卡 || 3 | 农行卡 || 4 | 工商卡 || 5 | 邮政卡 |+ ------+-----------+

INSERTINTOperson VALUES( 1, '张三', 1), ( 2, '李四', 3), ( 3, '王五', 6);SELECT* FROMperson;+ ------+--------+--------+| id | name | cardId |+ ------+--------+--------+| 1 | 张三 | 1 || 2 | 李四 | 3 || 3 | 王五 | 6 |+ ------+--------+--------+

分析两张表发现,person表并没有为cardId字段设置一个在card表中对应的id外键。如果设置了的话,person中cardId字段值为6的行就插不进去,因为该cardId值在card表中并没有。

内连接

要查询这两张表中有关系的数据,可以使用INNER JOIN( 内连接 ) 将它们连接在一起。

-- INNER JOIN: 表示为内连接,将两张表拼接在一起。-- on: 表示要执行某个条件。SELECT* FROMperson INNERJOINcard onperson.cardId = card.id;+ ------+--------+--------+------+-----------+| id | name | cardId | id | name |+ ------+--------+--------+------+-----------+| 1 | 张三 | 1 | 1 | 饭卡 || 2 | 李四 | 3 | 3 | 农行卡 |+ ------+--------+--------+------+-----------+-- 将 INNER 关键字省略掉,结果也是一样的。-- SELECT * FROM person JOIN card on person.cardId = card.id;注意:card 的整张表被连接到了右边。

左外连接

完整显示左边的表 (person) ,右边的表如果符合条件就显示,不符合则补NULL。

-- LEFT JOIN 也叫做 LEFT OUTER JOIN,用这两种方式的查询结果是一样的。SELECT * FROM person LEFT JOIN card on person.cardId = card.id;+------+--------+--------+------+-----------+| id |name | cardId |id | name |+------+--------+--------+------+-----------+| 1 |张三 | 1 |1| 饭卡 || 2 |李四 | 3 |3| 农行卡 || 3 |王五 | 6 |NULL | NULL |+------+--------+--------+------+-----------+

右外链接

完整显示右边的表 (card) ,左边的表如果符合条件就显示,不符合则补NULL。

SELECT * FROM person RIGHT JOIN card on person.cardId = card.id;+------+--------+--------+------+-----------+| id |name | cardId |id | name |+------+--------+--------+------+-----------+| 1 |张三 | 1 |1| 饭卡 || 2 |李四 | 3 |3| 农行卡 || NULL |NULL | NULL |2| 建行卡 || NULL |NULL | NULL |4| 工商卡 || NULL |NULL | NULL |5| 邮政卡 |+------+--------+--------+------+-----------+

全外链接

完整显示两张表的全部数据。

-- MySQL 不支持这种语法的全外连接-- SELECT * FROM person FULL JOIN card on person.cardId = card.id;-- 出现错误:-- ERROR 1054( 42S22): Unknown column 'person.cardId'in'on clause'-- MySQL全连接语法,使用 UNION 将两张表合并在一起。SELECT * FROM person LEFT JOIN card on person.cardId = card.idUNIONSELECT * FROM person RIGHT JOIN card on person.cardId = card.id;+------+--------+--------+------+-----------+| id |name | cardId |id | name |+------+--------+--------+------+-----------+| 1 |张三 | 1 |1| 饭卡 || 2 |李四 | 3 |3| 农行卡 || 3 |王五 | 6 |NULL | NULL || NULL |NULL | NULL |2| 建行卡 || NULL |NULL | NULL |4| 工商卡 || NULL |NULL | NULL |5| 邮政卡 |+------+--------+--------+------+-----------+

全文到这里撒花完结~

注:文章首发于知乎专栏,已授权数据不吹牛原创发表。

“干货!”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值