上次博文引用了各链接的示意图,未作详述,本文补充对数据库各链接的实例描述。sql
数据为klass
与student
的关系,班级一对多学生,没有加外键。数据库
数据关系以下:1
班的Hello Kitty
和史努比,2
班的米老鼠和唐老鸭,3
班没学生,葫芦娃没有班级。spa
关系型数据库,即数据之间是有所关系的。3d
就如咱们当前场景下的klass
与student
表同样,两表中的数据在实际的业务场景中是有所关联的,学生属于哪一个班级,这种多对一的关系,咱们在学生表中加上klass_id
一列存储这种关系。code
班级与学生的关系经过klass_id
进行维护。blog
简单的单表查询:get
SELECT * FROM `klass`;
若是想同时看教师和班级的数据,就须要进行多表查询了:it
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass`, `student` WHERE `klass`.`id` = `student`.`klass_id`;
进行多表查询时,实际上是将两表的记录先作笛卡尔积,再根据WHERE
条件对数据进行过滤。io
不加WHERE
条件的示例:class
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass`, `student`;
很惭愧,从我学数据库到如今,每次我手写这样需求的SQL
,都是使用的这种方法进行多表查询。
试想,若是咱们全部的多表查询,都使用WHERE
进行过滤,这会形成一个很严重的问题。
若是查询条件很复杂的话,会致使WHERE
语句不只充斥着数据表层面的链接条件,还充斥着各类业务条件,会让WHERE
语句很不直观。
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass`, `student` WHERE `klass`.`id` = `student`.`klass_id`;
参考问题:INNER JOIN ON vs WHERE clause - StackOverflow
这种场景下推荐使用内链接代替WHERE
。
内链接可更好地完成上述需求:
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass` INNER JOIN `student` ON `klass`.`id` = `student`.`klass_id`;
而且,链接的条件写在ON
里,WHERE
只写业务条件,更直观。
内链接:内链接基于链接谓词将两张表(如A
和B
)的列组合在一块儿,产生新的结果表。查询会将A
表的每一行和B
表的每一行进行比较,并找出知足链接谓词的组合。当链接谓词被知足,A
和B
中匹配的行会按列组合(并排组合)成结果集中的一行。
示例数据有三个班,可是3
班由于没有任何学生与之关联,因此不符合查询谓语中的klass.id = student.klass_id
,因此没有3
班的信息。
一样地,由于学生“葫芦娃”没有班级,也不符合查询条件,一样没有出如今内链接的查询 结果中。
注:在表链接中NULL != NULL
若是想让数据显示彻底,就须要左链接与右链接了。
klass
表链接student
表,klass
算左表,student
算右表。
左链接,显示左表全部数据:
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass` LEFT JOIN `student` ON `klass`.`id` = `student`.`klass_id`;
3
班在左链接中出现了:
右链接,显示右表全部数据:
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass` RIGHT JOIN `student` ON `klass`.`id` = `student`.`klass_id`;
“葫芦娃”在右链接中出现了:
宝剑锋从磨砺出,梅花香自苦寒来。