学习本节会遇到很多例子,想要查看例子中用到表结构,请访问:表结构参考
学习完本章,对于初学者,能掌握:
1.使用等值和不等值连接在SELECT 语句中查询多个表中的数据。
2.使用自连接。
3.使用外连接查询不满足连接条件的数据。
防止笛卡尔积:
在查询过程中,要避免笛卡尔积,如果在查询中省略连接条件、连接条件无效、所有表中的所有行互相连接,那么会产生笛卡尔积。为了避免笛卡尔积,必须要在where中加入有效的连接条件。
等值连接查询:
1 SELECT employees.employee_id, employees.last_name, 2 employees.department_id, departments.department_id, 3 departments.location_id 4 FROM employees, departments 5 WHERE employees.department_id = departments.department_id;
使用别名可以简化查询,可以提高执行效率,在生产过程中可以写成:
1 SELECT e.employee_id, e.last_name, e.department_id, 2 d.department_id, d.location_id 3 FROM employees e , departments d 4 WHERE e.department_id = d.department_id;
连接多个表:
连接 n个表,至少需要 n-1个连接条件。 例如:连接三个表,至少需要两个连接条件。例如:查询出公司员工的 last_name, department_name, city;
1 select e.last_name,d.department_name,l.city 2 from employees e,departments d,locations l 3 where e.department_id = d.department_id and d.location_id = l.location_id;
非等值连接:
例如:EMPLOYEES表中的列工资应在JOB_GRADES表中的最高工资与最低工资之间
1 SELECT e.last_name, e.salary, j.grade_level 2 FROM employees e, job_grades j 3 WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
内连接和外连接:
内连接是指:合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行。
外连接包含左外连接和右外连接:两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL). 外连接的 WHERE 子句条件类似于内部连接, 但连接条件中没有匹配行的表的列后面要加外连接运算符, 即用圆括号括起来的加号(+).
外连接的语法:
使用外连接可以查询不满足连接条件的数据。
外连接的符号是 (+)
右外连接:
1 SELECT table1.column, table2.column 2 FROM table1, table2 3 WHERE table1.column(+) = table2.column;
左外连接:
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column = table2.column(+);
这是基本的内连接和外连接,下面将重点学习一下SQL: 1999 语法连接。
SQL: 1999 语法连接:
使用连接在多个表中查询数据,包含叉集、自然连接、using子句创建连接、使用on子句创建连接、内连接、左外连接、右外连接、满外连接:
SELECT table1.column, table2.column
FROM table1
[CROSS JOIN table2] |
[NATURAL JOIN table2] |
[JOIN table2 USING (column_name)] |
[JOIN table2
ON(table1.column_name = table2.column_name)] |
[LEFT|RIGHT|FULL OUTER JOIN table2
ON (table1.column_name = table2.column_name)];
叉集(这里只做了解):
1.使用CROSS JOIN 子句使连接的表产生叉集。
2.叉集和笛卡尔集是相同的。
例如:
1 SELECT last_name, department_name 2 FROM employees 3 CROSS JOIN departments
自然连接:
1.NATURAL JOIN 子句,会以两个表中具有相同名字的列为条件创建等值连接。
2.在表中查询满足等值条件的数据。
3.如果只是列名相同而数据类型不同,则会产生错误。
返回的是,两个表中具有相同名字的列的“且、交集”,而非“或,并集”。即:比如employee类和department类都有department_id和manager_id,返回二者都相同的结果。
1 SELECT department_id, department_name, 2 location_id, city 3 FROM departments 4 NATURAL JOIN locations;
using子句:
1.在NATURAL JOIN 子句创建等值连接时,可以使用 USING 子句指定等值连接中需要用到的列。
2.使用 USING 可以在有多个列满足条件时进行选择。
3.不要给选中的列中加上表名前缀或别名。
4.JOIN 和 USING 子句经常同时使用。
会自动匹配表中相同的列,可多列匹配;
1 select last_name,department_name 2 from employees 3 natural join departments ;
如果加上using,则会选择using中的列进行匹配。 5 select last_name,department_name 6 from employees 7 join departments using (department_id);
on子句:
1.自然连接中是以具有相同名字的列为连接条件的,可以使用 ON 子句指定额外的连接条件。
2.这个连接条件是与其它条件分开的。
3.ON 子句使语句具有更高的易读性。
例如通过on子句关联employees和departments表:
1 SELECT e.employee_id, e.last_name, e.department_id, 2 d.department_id, d.location_id 3 FROM employees e JOIN departments d 4 ON (e.department_id = d.department_id);
通过on子句进行employees、departments。locations多表连接:
1 SELECT employee_id, city, department_name 2 FROM employees e 3 JOIN departments d 4 ON d.department_id = e.department_id 5 JOIN locations l 6 ON d.location_id = l.location_id;
内连接:
在SQL: 1999中,内连接只返回满足连接条件的数据。
左外连接(LEFT OUTER JOIN):
两个表在连接过程中除了返回满足连接条件的行以外还返回左表中不满足条件的行,这种连接称为左外连接。
1 SELECT e.last_name, e.department_id, d.department_name 2 FROM employees e 3 LEFT OUTER JOIN departments d 4 ON (e.department_id = d.department_id) ;
右外连接(RIGHT OUTER JOIN):
两个表在连接过程中除了返回满足连接条件的行以外还返回右表中不满足条件的行,这种连接称为右外连接。
1 SELECT e.last_name, e.department_id, d.department_name 2 FROM employees e 3 RIGHT OUTER JOIN departments d 4 ON (e.department_id = d.department_id) ;
满外连接(FULL OUTER JOIN):
两个表在连接过程中除了返回满足连接条件的行以外还返回两个表中不满足条件的行 ,这种连接称为满外连接。
1 SELECT e.last_name, e.department_id, d.department_name 2 FROM employees e 3 FULL OUTER JOIN departments d 4 ON (e.department_id = d.department_id) ;
通过上面的学习,sql语法的多表查询一般有四种方法:
方式一(通用型):SELECT ... FROM ... WHERE
1 SELECT e.last_name,e.department_id,d.department_name 2 FROM employees e,departments d 3 where e.department_id = d.department_id
方式二:SELECT ... FROM ... NATURAL JOIN ...
有局限性:会自动连接两个表中相同的列(可能有多个:department_id和manager_id)
1 SELECT last_name,department_id,department_name 2 FROM employees 3 NATURAL JOIN departments
方式三:SELECT ... JOIN ... USING ...
有局限性:好于方式二,但若多表的连接列列名不同,此法不合适
1 SELECT last_name,department_id,department_name 2 FROM employees 3 JOIN departments 4 USING(department_id)
方式四:SELECT ... FROM ... JOIN ... ON ...
常用方式,较方式一,更易实现外联接(左、右、满)
SELECT last_name,e.department_id,department_name FROM employees e JOIN departments d ON e.department_id = d.department_id