SQL学习指南 -- 多表查询
customer数据表包含599行,address数据表包含603行,而结果集中的361,197行是从哪里来的呢?仔细观察,会发现很多客户居住的街道地址是一样的。这是因为查询并没有指定两个数据表应该如何连接,数据库服务器就生成了笛卡儿积(Cartesian product),也就是两个数据表的所有排列组合(599个客户 603个地址= 361,197种排列组合)。这种连接被称为交叉连接(cross join),很少会用到(至少不会特意用到)。 这是笛卡尔交叉
笛卡尔交叉比较多,属于所有内容都需要显示。
如果一个数据表中的address_id列的值在另一个数据表中不存在,则包含该值的行连接失败,相应行不会出现在结果集中。这就是内连接,也是最常用的连接。 on 选择:需要连接的关键字。
如果要将一个数据表中的所有行全部纳入结果集,不管其在另一个数据表中是否存在匹配,则需要指定外连接(outer join)
如果没有指定连接类型,那么服务器会默认使用内连接。正如本书随后要介绍的,连接类型不止一种,最好养成明确指定所需的连接类型的习惯,尤其是为将来可能使用/维护查询的其他人考虑。 比如加上inner join 连接。
内连接需要加上inner join,和on的具体条件。
连接3个数据表的方法与连接2个数据表差不多,只有一处细微的差别。在2个数据表的连接查询中,from子句包含2个数据表和1种连接类型,on子句指定2个数据表如何连接。对于3个数据表的连接,from子句包含3个数据表和2种连接类型,再加上2个on子句。
2个连接方式,和2个on的关键词。
连接顺序重要吗?
如果你对这3个版本的customer/address/city查询都产生同样的结果感到疑惑,记住,SQL是一种非过程化语言,也就是说只需要描述检索的内容和涉及的数据库对象,由数据库服务器负责确定如何以最佳方式执行查询。服务器使用从数据库对象收集的统计信息,在3个数据表中选择一个作为起点(所选择的数据表被称为驱动表),然后确定其他数据表的连接顺序。因此,各数据表在from子句中出现的顺序并不重要。