【OracleDB】 06 多表查询
多表查询的目的:
从两张以上的数据表中查询每张表的字段

笛卡尔集的问题:
查询职员表一共107条记录
select count(employee_id) from employees;

查询部门表,一共27条记录
select count(department_id)from departments;

我们不按照任何的数据表的关系,合并查询,就会出现这样的状况:
select 107*27 from dual;
也就是表1的每一个记录对应表2的所有记录
查询的结果就是N张表之间的所有记录乘积

笛卡尔积产生的条件:
- 省略连接条件
- 连接条件无效
- 所有表的所有记录互相连接
【使用WHERE子句,加入有效的筛选条件以过滤】
Oracle的连接查询:
语法公式:
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column1 = table2.column2;
- 在 WHERE 子句中写入连接条件。
- 在表中有相同列时,在列名之前加上表名前缀
等值连接
SELECT employees.employee_id, employees.last_name, employees.department_id, departments.department_id, departments.location_id FROM employees, departments WHERE employees.department_id = departments.department_id;
使用别名简化标识和书写
SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id FROM employees e , departments d WHERE e.department_id = d.department_id;
【连接 n个表,至少需要 n-1个连接条件】
练习:
查询出公司员工的 last_name, department_name, city
非等值连接
案例:
EMPLOYEES表中的列工资 应在JOB_GRADES表中的最高 工资与最低工资之间
SELECT e.last_name, e.salary, j.grade_level FROM employees e, job_grades j WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
内连接和外连接
内连接:
合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行
外连接:
两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。
没有匹配的行时, 结果表中相应的列为空(NULL).
外连接的 WHERE 子句条件类似于内部连接, 但连接条件中没有匹配行的表的列后面要加外连接运算符, 即用圆括号括起来的加号(+).
外连接的语法公式:
左外连接
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column = table2.column(+);
右外连接
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column(+) = table2.column;
【使用外连接可以查询不满足连接条件的数据。 外连接的符号是 (+)】
案例:
SELECT e.last_name, e.department_id, d.department_name FROM employees e, departments d WHERE e.department_id(+) = d.department_id ;
自连接
练习:
查询出 last_name 为 ‘Chen’ 的员工的 manager 的信息
练习2:
查询employees表,返回“Xxx works for Xxx”
写法:
SELECT worker.last_name || ' works for ' || manager.last_name FROM employees worker, employees manager WHERE worker.manager_id = manager.employee_id ;
Oracle99SQL语法:
使用连接从多个表中查询数据:
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)];
叉集 CROSS JOIN
使用CROSS JOIN 子句使连接的表产生叉集。
叉集和笛卡尔集是相同的。
SELECT last_name, department_name FROM employees CROSS JOIN departments ;
自然连接 NATURAL JOIN
- NATURAL JOIN 子句,会以两个表中具有相同名字的列为条件创建等值连接。
- 在表中查询满足等值条件的数据。
- 如果只是列名相同而数据类型不同,则会产生错误。
返回的是,两个表中具有相同名字的列的“且、交集”,而非“或,并集”。
即:比如employee类和department类都有department_id和manager_id,返回二者都相同的结果。
自然连接
SELECT department_id, department_name, location_id, city FROM departments NATURAL JOIN locations ;
使用 USING 子句创建连接
- 在NATURAL JOIN 子句创建等值连接时,可以使用 USING 子句指定等值连接中需要用到的列。
- 使用 USING 可以在有多个列满足条件时进行选择。
- 不要给选中的列中加上表名前缀或别名。
- JOIN 和 USING 子句经常同时使用。
使用自然连接
select last_name,department_name from employees natural join departments ;
使用USING子句
select last_name,department_name from employees join departments using (department_id);
案例:
SELECT e.employee_id, e.last_name, d.location_id FROM employees e JOIN departments d USING (department_id) ;
使用ON 子句创建连接
- 自然连接中是以具有相同名字的列为连接条件的。
- 可以使用 ON 子句指定额外的连接条件。
- 这个连接条件是与其它条件分开的。
- ON 子句使语句具有更高的易读性。
案例:
SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id FROM employees e JOIN departments d ON (e.department_id = d.department_id);
使用 ON 子句创建多表连接
SELECT employee_id, city, department_name FROM employees e JOIN departments d ON d.department_id = e.department_id JOIN locations l ON d.location_id = l.location_id;
总结:内连接和外连接
- 在SQL: 1999中,内连接只返回满足连接条件的数据
- 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右) 外连接。
- 两个表在连接过程中除了返回满足连接条件的行以外还返回两个表中不满足条件的行 ,这种连接称为满 外连接。
左外
SELECT e.last_name, e.department_id, d.department_name FROM employees e LEFT OUTER JOIN departments d ON (e.department_id = d.department_id) ;
右外
SELECT e.last_name, e.department_id, d.department_name FROM employees e RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id) ;
全外
SELECT e.last_name, e.department_id, d.department_name FROM employees e FULL OUTER JOIN departments d ON (e.department_id = d.department_id) ;
SQL语句的多表查询方式:
例如:按照department_id查询employees(员工表)和departments(部门表)的信息。
方式一(通用型):SELECT ... FROM ... WHERE
SELECT e.last_name,e.department_id,d.department_name FROM employees e,departments d where e.department_id = d.department_id
方式二:SELECT ... FROM ... NATURAL JOIN ...
有局限性:会自动连接两个表中相同的列(可能有多个:department_id和manager_id)
SELECT last_name,department_id,department_name FROM employees NATURAL JOIN departments
方式三:SELECT ... JOIN ... USING ...
有局限性:好于方式二,但若多表的连接列列名不同,此法不合适
SELECT last_name,department_id,department_name FROM employees JOIN departments 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
--内连接 1) --等值连接 --不等值连接 2) --非自连接 --自连接 --外连接 --左外连接、右外连接、满外连接

浙公网安备 33010602011771号