多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。
前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立了外键,也可能没有建立外键。比如:员工表和部门表,这两个表依靠“部门编号”进行关联。
#查询员工名为’ Abel’的人在哪个城市工作?
SELECT *
FROM employees
WHERE last_name = ‘Abel’;
SELECT *
FROM departments
WHERE department_id = 80;
SELECT *
FROM locations
WHERE location_id = 2500;
首先可以合成一张表。为什么不这样做呢?
将多个表合成一张表,会有大量的冗余字段。其次对于很多为NULL的字段,会浪费很多空间
查询一张表的数据,会将查询到的数据从磁盘中加载到内存中。一次IO加载的数据量是有限的,例如一次IO加载1万个字段;对于小表来说如果一行只有10个字段,一次IO加载的行就会更多;而对于大表来说如果一行有1000个字段一次IO加载的行就会很少。对于大表进行select * 来说就需要更多次IO才可以将表中所有数据加载到内存。效率也就低
例如查询操作,原来3张表,对于查询其中一张表,其他2张表就不涉及锁定问题,其他用户要对剩余2张表进行查询就可以随时进行。而如果合并为一张表,一个用户进行查询操作就会将整个表进行锁定,其他用户想进行其他字段的查询就会阻塞。因此多表对于多进程来说效率更高,表的粒度越小,更利于并发
查询结果:
表的查询如何实现?:出现笛卡尔积的错误
#错误的实现方式:每个员工都与每个部门匹配了一遍。
SELECT employee_id, department_name
FROM employees,departments;#查询出2889条记录
SELECT*
FROM employees;#107条记录
SELECT 2889 / 107
FROM DUAL;
SELECT *
FROM departments; #27条记录
笛卡尔乘积是一个数学运算。假设我有两个集合X和Y,那么X和Y的笛卡尔积就是X和Y的所有可能组合,也就是第一个对象来自于X,第二个对象来自于Y的所有可能。组合的个数即为两个集合中元素个数的乘积数。
SQL92中,笛卡尔积也称为交叉连接,英文是CROSS JOIN。在SQL99中也是使用CROSS JOIN表示交叉连接。它的作用就是可以把任意表进行连接,即使这两张表不相关。在MySQL中如下情况会出现笛卡尔积:
SELECT table1.column,table2.column
FROM table1, table2
WHERE table1.column1 = table2.column2 ;#连接条件
#1。熟悉常见的几个表
DESC employees;
DESC departments ;
DEsc locations;
#查询员工名为’ Abel’的人在哪个城市工作?
SELECT *
FROM employees
WHERE last_name = ‘Abel’;
SELECT *
FROM departments
WHERE department_id = 80;
SELECT *
FROM locations
WHERE location_id = 2500;
#2.表的查询如何实现?:出现笛卡尔积的错误
#错误的实现方式:每个员工都与每个部门匹配了一遍。
SELECT employee_id, department_name
FROM employees,departments;#查询出2889条记录
SELECT*
FROM employees;#107条记录
SELECT 2889 / 107
FROM DUAL;
SELECT *
FROM departments; #27条记录
#4,如果查询语句中出现了多个表中都存在的字段,则必须指明此字段所在的表。
SELECT employee_id, department_name,employees.department_id
FROM employees,departments
WHERE employees.department_id=departments.department_id;
SELECT employees.employee_id, departments.department_name,employees.department_id
FROM employees,departments
WHERE employees.department_id=departments.department_id;
#建议:从sql优化的角度,建议多表查询时,每个字段前都指明其所在的表。
#5.可以给表起别名,在SELECT和WHERE中使用表的别名。
#如果给表起了别名,一旦在SELECT或WHERE中使用表名的话,则必须使用表的别名,而不能再使用表的原名。
SELECT emp.employee_id, dept.department_name,emp.department_id
FROM employees emp,departments dept
WHERE emp.department_id=dept.department_id;
#6.如果有n个表实现多表的查询,则需要至少n-1个连接条件
#练习:查询员工的employee_id, last_name , department_name, city
SELECT employee_id,last_name , department_name , city,e.department_id,l.location_id
FROM employees e , departments d,locations l
WHERE e.department_id= d.department_id
AND d.location_id= l.location_id;
利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同,并且相互对应。各个SELECT语句之间使用UNION或UNION ALL关键字分隔。
不适用于自连接
表连接的约束条件可以有三种方式: WHERE,ON,USING
在正式开始讲连接表的种类时,我们首先需要知道SQL存在不同版本的标准规范,因为不同规范下的表连接操作是有区别的。
SQL有两个主要的标准,分别是SQL92和 SQL99。92和99代表了标准提出的时间,SQL92就是92年提出的标准规范。当然除了SQL92和sQL99以外,还存在SQL-86、SQL-89、SQL:2003、SQL:2008、SQL:2011和SQL:2016等其他的标准。
这么多标准,到底该学习哪个呢?实际上最重要的SQL标准就是SQL92和SQL99。一般来说SQL92的形式更简单,但是写的SsQL语句会比较长,可读性较差。而SQL99相比于SQL92来说,语法更加复杂,但可读性更强。我们从这两个标准发布的页数也能看出,SQL92的标准有500页,而SQL99标准超过了1000页。实际上从
sQL99之后,很少有人能掌握所有内容,因为确实太多了。就好比我们使用Windows、Linux和Office的时候,很少有人能掌握全部内容一样。我们只需要掌握一些核心的功能,满足日常工作的需求即可。
SQL92和SQL99是经典的SQL标准,也分别叫做SQL-2和SQL-3标准。也正是在这两个标准发布之后,SQL影响力越来越大,甚至超越了数据库领域。现如今SQL已经不仅仅是数据库领域的主流语言,还是信息领域中信息处理的主流语言。在图形检索、图像检索以及语音检索中都能看到SQL语言的使用。