lesson05 从多表中查询数据

74
5-1 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved. Oracle OCP Oracle OCP Oracle OCP Oracle OCP 考试系列培训 1Z0-007 Lesson5 1Z0-007 Lesson5 1Z0-007 Lesson5 1Z0-007 Lesson5 www www www www . OracleOnLinux OracleOnLinux OracleOnLinux OracleOnLinux . cn cn cn cn

Upload: renguzi

Post on 27-May-2015

392 views

Category:

Technology


24 download

DESCRIPTION

Oracle OCP考试之007第5章,学会从多表中查询数据

TRANSCRIPT

5-1 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Oracle OCPOracle OCPOracle OCPOracle OCP 考试系列培训之

1Z0-007 Lesson51Z0-007 Lesson51Z0-007 Lesson51Z0-007 Lesson5wwwwwwwwwwww....OracleOnLinuxOracleOnLinuxOracleOnLinuxOracleOnLinux....cncncncn

5555Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.5-2

Displaying Data Displaying Data Displaying Data Displaying Data from Multiple Tablesfrom Multiple Tablesfrom Multiple Tablesfrom Multiple Tables

5-3 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

ObjectivesObjectivesObjectivesObjectives

After completing this lesson, you should be able to do After completing this lesson, you should be able to do After completing this lesson, you should be able to do After completing this lesson, you should be able to do the following:the following:the following:the following:• Write Write Write Write SELECTSELECTSELECTSELECT statements to access data from statements to access data from statements to access data from statements to access data from

more than one table using equijoins and non-more than one table using equijoins and non-more than one table using equijoins and non-more than one table using equijoins and non-equijoinsequijoinsequijoinsequijoins

• Join a table to itself by using a self-joinJoin a table to itself by using a self-joinJoin a table to itself by using a self-joinJoin a table to itself by using a self-join• View data that generally does not meet a join View data that generally does not meet a join View data that generally does not meet a join View data that generally does not meet a join

condition by using outer joinscondition by using outer joinscondition by using outer joinscondition by using outer joins• Generate a Cartesian product of all rows from two Generate a Cartesian product of all rows from two Generate a Cartesian product of all rows from two Generate a Cartesian product of all rows from two

or more tablesor more tablesor more tablesor more tables

5-4 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Obtaining Data from Multiple TablesObtaining Data from Multiple TablesObtaining Data from Multiple TablesObtaining Data from Multiple Tables

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES DEPARTMENTS DEPARTMENTS DEPARTMENTS DEPARTMENTS

…………

…………

5-5 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Oracle Oracle Oracle Oracle 的多表查询

使用连接从多个表中查询数据;;;;

产生笛卡尔乘积....

SELECTSELECTSELECTSELECT last_name, last_name, last_name, last_name,department_namedepartment_namedepartment_namedepartment_nameFROMFROMFROMFROM employees,departmentsemployees,departmentsemployees,departmentsemployees,departments;;;;SELECTSELECTSELECTSELECT last_name, last_name, last_name, last_name,department_namedepartment_namedepartment_namedepartment_nameFROMFROMFROMFROM employees,departmentsemployees,departmentsemployees,departmentsemployees,departments;;;;

5-6 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

等值连接 -- -- -- -- EquijoinEquijoinEquijoinEquijoin非等值连接 -- -- -- -- Non-equijoinNon-equijoinNon-equijoinNon-equijoin外连接 -- -- -- -- Outer joinOuter joinOuter joinOuter join自连接 -- -- -- -- Self joinSelf joinSelf joinSelf join

连接的类型

交叉连接 -- -- -- -- Cross joinsCross joinsCross joinsCross joins自然连接 -- -- -- -- Natural joinsNatural joinsNatural joinsNatural joins使用UsingUsingUsingUsing子句的连接

完全外连接或者左、右外连接

SQL: 1999 SQL: 1999 SQL: 1999 SQL: 1999 适应性连接::::

Oracle Oracle Oracle Oracle 以前的连接 (8 (8 (8 (8iiii and priorand priorand priorand prior 90SQL 90SQL 90SQL 90SQL):):):):

5-7 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

使用 Oracle Oracle Oracle Oracle 的语法连接多个表

使用连接从多个表中查询数据....

• 在 WHEREWHEREWHEREWHERE 子句中写入连接条件....• 当多个表中有重名列时,在列的名字前加上表名作为

前缀....

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1, table2table1, table2table1, table2table1, table2WHEREWHEREWHEREWHERE table1.column1 table1.column1 table1.column1 table1.column1 ==== table2.column2; table2.column2; table2.column2; table2.column2;

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1, table2table1, table2table1, table2table1, table2WHEREWHEREWHEREWHERE table1.column1 table1.column1 table1.column1 table1.column1 ==== table2.column2; table2.column2; table2.column2; table2.column2;

5-8 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

什么是等值连接????EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES DEPARTMENTS DEPARTMENTS DEPARTMENTS DEPARTMENTS

Foreign keyForeign keyForeign keyForeign key Primary keyPrimary keyPrimary keyPrimary key

………… …………

5-9 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, employees.department_id, departments.department_id, employees.department_id, departments.department_id, employees.department_id, departments.department_id, employees.department_id, departments.department_id, departments.location_id departments.location_id departments.location_id departments.location_idFROM employees, departmentsFROM employees, departmentsFROM employees, departmentsFROM employees, departmentsWHERE employees.department_id = departments.department_id;WHERE employees.department_id = departments.department_id;WHERE employees.department_id = departments.department_id;WHERE employees.department_id = departments.department_id;

使用等值连接查询数据

…………

5-10 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

使用 ANDANDANDAND 操作符增加查询条件

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES DEPARTMENTSDEPARTMENTSDEPARTMENTSDEPARTMENTS

………… …………

5-11 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, employees.department_id, departments.department_id, employees.department_id, departments.department_id, employees.department_id, departments.department_id, employees.department_id, departments.department_id, departments.location_id departments.location_id departments.location_id departments.location_idFROM employees, departmentsFROM employees, departmentsFROM employees, departmentsFROM employees, departmentsWHERE employees.department_id = departments.department_idWHERE employees.department_id = departments.department_idWHERE employees.department_id = departments.department_idWHERE employees.department_id = departments.department_idAND employees.salary>10000AND employees.salary>10000AND employees.salary>10000AND employees.salary>10000 ;;;;

使用 ANDANDANDAND 操作符增加查询条件

5-12 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.employee_id, e.last_name, e.department_id,SELECT e.employee_id, e.last_name, e.department_id,SELECT e.employee_id, e.last_name, e.department_id,SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_idFROM employees e , departments dFROM employees e , departments dFROM employees e , departments dFROM employees e , departments dWHERE e.department_id = d.department_id;WHERE e.department_id = d.department_id;WHERE e.department_id = d.department_id;WHERE e.department_id = d.department_id;

使用表的别名

• 使用表的别名简化了查询....• 提供虚拟数据源,自连接中更能体现....

• 表别名不能与表名混用

SELECT e.employee_id, e.last_name, e.department_id,SELECT e.employee_id, e.last_name, e.department_id,SELECT e.employee_id, e.last_name, e.department_id,SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.department_id, d.department_id, d.department_id, departmentsdepartmentsdepartmentsdepartments.location_id.location_id.location_id.location_idFROM employees e , departments dFROM employees e , departments dFROM employees e , departments dFROM employees e , departments dWHERE e.department_id = d.department_id;WHERE e.department_id = d.department_id;WHERE e.department_id = d.department_id;WHERE e.department_id = d.department_id;

5-13 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

对多表作等值连接查询

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES LOCATIONSLOCATIONSLOCATIONSLOCATIONS DEPARTMENTSDEPARTMENTSDEPARTMENTSDEPARTMENTS

为了连接nnnn个表, , , , 至少需要n-1n-1n-1n-1个连接条件....例如,,,,为了连接三个表,,,,至少需要两个连接条件....

…………

5-14 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

对多表作等值连接查询

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES LOCATIONSLOCATIONSLOCATIONSLOCATIONS DEPARTMENTSDEPARTMENTSDEPARTMENTSDEPARTMENTS

LAST_NAME DEPARTMENT_NAME JOB_TITLE CITYLAST_NAME DEPARTMENT_NAME JOB_TITLE CITYLAST_NAME DEPARTMENT_NAME JOB_TITLE CITYLAST_NAME DEPARTMENT_NAME JOB_TITLE CITY--------------- ------------------------------ ----------------------------------- --------------------------------------------- ------------------------------ ----------------------------------- --------------------------------------------- ------------------------------ ----------------------------------- --------------------------------------------- ------------------------------ ----------------------------------- ------------------------------King King King King Executive President Executive President Executive President Executive President Seattle Seattle Seattle SeattleDe Haan Executive Administration Vice President SeattleDe Haan Executive Administration Vice President SeattleDe Haan Executive Administration Vice President SeattleDe Haan Executive Administration Vice President SeattleKochhar Executive Administration Vice President SeattleKochhar Executive Administration Vice President SeattleKochhar Executive Administration Vice President SeattleKochhar Executive Administration Vice President Seattle........................

JOBJOBJOBJOBSSSS col job_title for a30col job_title for a30col job_title for a30col job_title for a30col last_name for a20col last_name for a20col last_name for a20col last_name for a20col department_name for a20col department_name for a20col department_name for a20col department_name for a20set linesize 120set linesize 120set linesize 120set linesize 120SELECTSELECTSELECTSELECT e.last_name,d.department_name,j.job_title,l.city e.last_name,d.department_name,j.job_title,l.city e.last_name,d.department_name,j.job_title,l.city e.last_name,d.department_name,j.job_title,l.cityFROMFROMFROMFROM employees e,departments d,jobs j,locations l employees e,departments d,jobs j,locations l employees e,departments d,jobs j,locations l employees e,departments d,jobs j,locations lWHEREWHEREWHEREWHERE e.department_id=d.department_id e.department_id=d.department_id e.department_id=d.department_id e.department_id=d.department_idANDANDANDAND e.job_id=j.job_id e.job_id=j.job_id e.job_id=j.job_id e.job_id=j.job_idANDANDANDAND d.location_id=l.location_id; d.location_id=l.location_id; d.location_id=l.location_id; d.location_id=l.location_id;

5-15 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

非等值连接

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES JOB_GRADESJOB_GRADESJOB_GRADESJOB_GRADES

在 EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES 表中所有薪水

位于JOB_GRADESJOB_GRADESJOB_GRADESJOB_GRADES表最低薪水

和最高薪水之间雇员的薪水信

息....

…………

除等值连接之外的所有连接都认为是非等值连接。

5-16 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

使用非等值连接查询数据

SELECT e.last_name, e.salary, j.grade_levelSELECT e.last_name, e.salary, j.grade_levelSELECT e.last_name, e.salary, j.grade_levelSELECT e.last_name, e.salary, j.grade_levelFROM employees e, job_grades jFROM employees e, job_grades jFROM employees e, job_grades jFROM employees e, job_grades jWHERE e.salary WHERE e.salary WHERE e.salary WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal; BETWEEN j.lowest_sal AND j.highest_sal; BETWEEN j.lowest_sal AND j.highest_sal; BETWEEN j.lowest_sal AND j.highest_sal;

…………

5-17 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

外连接

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEESDEPARTMENTSDEPARTMENTSDEPARTMENTSDEPARTMENTS

没有雇员属于190190190190部门. . . .

…………

5-18 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

外连接的语法

• 为了看到那些不匹配的数据,必须使用外连接....• 外连接的操作符为 (+)(+)(+)(+)....• 不能把连接操作符(+)(+)(+)(+)同时运用在两端(99SQL(99SQL(99SQL(99SQL支持).).).).• 等值连接""""丢失""""记录,外连接则显示所有记录....

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1, table2table1, table2table1, table2table1, table2WHEREWHEREWHEREWHERE table1.columntable1.columntable1.columntable1.column(+)(+)(+)(+) ==== table2.column; table2.column; table2.column; table2.column;

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1, table2table1, table2table1, table2table1, table2WHEREWHEREWHEREWHERE table1.columntable1.columntable1.columntable1.column(+)(+)(+)(+) ==== table2.column; table2.column; table2.column; table2.column;

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1, table2table1, table2table1, table2table1, table2WHEREWHEREWHEREWHERE table1.column table1.column table1.column table1.column = = = = table2.columntable2.columntable2.columntable2.column(+)(+)(+)(+);;;;

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1, table2table1, table2table1, table2table1, table2WHEREWHEREWHEREWHERE table1.column table1.column table1.column table1.column = = = = table2.columntable2.columntable2.columntable2.column(+)(+)(+)(+);;;;

5-19 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameFROM employees e, departments dFROM employees e, departments dFROM employees e, departments dFROM employees e, departments d

WHERE e.department_id(+) = d.department_id ;WHERE e.department_id(+) = d.department_id ;WHERE e.department_id(+) = d.department_id ;WHERE e.department_id(+) = d.department_id ;

使用外连接

…………

5-20 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

自连接

EMPLOYEES (WORKER)EMPLOYEES (WORKER)EMPLOYEES (WORKER)EMPLOYEES (WORKER) EMPLOYEES (MANAGER)EMPLOYEES (MANAGER)EMPLOYEES (MANAGER)EMPLOYEES (MANAGER)

WORKERWORKERWORKERWORKER表中的MANAGER_IDMANAGER_IDMANAGER_IDMANAGER_ID 等于 MANAGERMANAGERMANAGERMANAGER 表中的EMPLOYEE_IDEMPLOYEE_IDEMPLOYEE_IDEMPLOYEE_ID....

………… …………

5-21 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

对一张表作自连接查询

SELECT worker.last_name || ' works for ' SELECT worker.last_name || ' works for ' SELECT worker.last_name || ' works for ' SELECT worker.last_name || ' works for ' || manager.last_name || manager.last_name || manager.last_name || manager.last_nameFROM employees worker, employees managerFROM employees worker, employees managerFROM employees worker, employees managerFROM employees worker, employees managerWHERE worker.manager_id = manager.employee_id ;WHERE worker.manager_id = manager.employee_id ;WHERE worker.manager_id = manager.employee_id ;WHERE worker.manager_id = manager.employee_id ;

…………

员工的管理者编号就是管理者作为员工的员工编号

5-22 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

使用 SQL: 1999 SQL: 1999 SQL: 1999 SQL: 1999 语法执行表的连接

使用连接从多个表中查询数据....

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1table1table1table1[CROSS JOIN [CROSS JOIN [CROSS JOIN [CROSS JOIN table2table2table2table2] |] |] |] |[NATURAL JOIN [NATURAL JOIN [NATURAL JOIN [NATURAL JOIN table2table2table2table2] |] |] |] |[JOIN [JOIN [JOIN [JOIN table2table2table2table2 USING ( USING ( USING ( USING (column_namecolumn_namecolumn_namecolumn_name)] |)] |)] |)] |[JOIN [JOIN [JOIN [JOIN table2table2table2table2 ON( ON( ON( ON(table1.column_nametable1.column_nametable1.column_nametable1.column_name = = = = table2.column_nametable2.column_nametable2.column_nametable2.column_name)] |)] |)] |)] |[LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN table2table2table2table2 ON ( ON ( ON ( ON (table1.column_nametable1.column_nametable1.column_nametable1.column_name = = = = table2.column_nametable2.column_nametable2.column_nametable2.column_name)];)];)];)];

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1table1table1table1[CROSS JOIN [CROSS JOIN [CROSS JOIN [CROSS JOIN table2table2table2table2] |] |] |] |[NATURAL JOIN [NATURAL JOIN [NATURAL JOIN [NATURAL JOIN table2table2table2table2] |] |] |] |[JOIN [JOIN [JOIN [JOIN table2table2table2table2 USING ( USING ( USING ( USING (column_namecolumn_namecolumn_namecolumn_name)] |)] |)] |)] |[JOIN [JOIN [JOIN [JOIN table2table2table2table2 ON( ON( ON( ON(table1.column_nametable1.column_nametable1.column_nametable1.column_name = = = = table2.column_nametable2.column_nametable2.column_nametable2.column_name)] |)] |)] |)] |[LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN table2table2table2table2 ON ( ON ( ON ( ON (table1.column_nametable1.column_nametable1.column_nametable1.column_name = = = = table2.column_nametable2.column_nametable2.column_nametable2.column_name)];)];)];)];

5-23 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

建立交叉连接

• CROSS JOINCROSS JOINCROSS JOINCROSS JOIN 子句产生两个表的交叉连接. . . . • 产生的结果等于两个表执行笛卡尔乘积. . . .

SELECT last_name, department_nameSELECT last_name, department_nameSELECT last_name, department_nameSELECT last_name, department_nameFROM employeesFROM employeesFROM employeesFROM employeesCROSS JOIN departments ;CROSS JOIN departments ;CROSS JOIN departments ;CROSS JOIN departments ;

…………

5-24 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

建立自然连接

• NATURAL JOINNATURAL JOINNATURAL JOINNATURAL JOIN 子句基于两个表中列名完全相同的多

个列产生连接....• 从两个表中选出连接列的值相等的所有行....• 如果两个列的名称相同,,,,但是具有不同的数据类型,则

查询会返回一个错误....– 字段名同,含义不同;(不想连接却连上了)

– 字段名不同,含义同;(想连却连不上)

– 字段名同,含义同;(不可以显示指定不连)

– 不能做非等值连接;

5-25 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT department_id, department_name,SELECT department_id, department_name,SELECT department_id, department_name,SELECT department_id, department_name, location_id, city location_id, city location_id, city location_id, cityFROM departmentsFROM departmentsFROM departmentsFROM departmentsNATURAL JOIN locations ;NATURAL JOIN locations ;NATURAL JOIN locations ;NATURAL JOIN locations ;

用自然连接查询数据

5-26 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

使用 USINGUSINGUSINGUSING 子句建立连接

• 如果某些列有相同的名称但数据类型不匹配,,,,自然连接将出错,可以在自然连接的 NATURAL JOINNATURAL JOINNATURAL JOINNATURAL JOIN 子句上使用 USINGUSINGUSINGUSING 子句来设置用于等值连接的列....

• 不要在引用列上使用表名或者别名作为前缀....• NATURAL JOINNATURAL JOINNATURAL JOINNATURAL JOIN 与 USINGUSINGUSINGUSING子句是相互独立的....

– 能解决同名不同意的问题;

– 解决不了同意不同名的问题;

5-27 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.employee_id, e.last_name, d.location_idSELECT e.employee_id, e.last_name, d.location_idSELECT e.employee_id, e.last_name, d.location_idSELECT e.employee_id, e.last_name, d.location_idFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dUSING (department_id) ;USING (department_id) ;USING (department_id) ;USING (department_id) ;

使用 USINGUSINGUSINGUSING 子句查询数据

…………

5-28 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

使用ONONONON子句建立连接

• 自然连接的条件是基于表中所有同名列的等值连接....• 为了设置任意的连接条件或者指定连接的列,需要使

用ONONONON子句....• 连接条件与其它的查询条件分开书写....• 使用ONONONON 子句使查询语句更容易理解....

5-29 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_idFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dON (e.department_id = d.department_id);ON (e.department_id = d.department_id);ON (e.department_id = d.department_id);ON (e.department_id = d.department_id);

使用 ONONONON 子句查询数据

…………

5-30 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

使用ONONONON子句建立Three-Way Three-Way Three-Way Three-Way 连接

SELECT employee_id, city, department_nameSELECT employee_id, city, department_nameSELECT employee_id, city, department_nameSELECT employee_id, city, department_nameFROM employees e FROM employees e FROM employees e FROM employees e JOIN departments dJOIN departments dJOIN departments dJOIN departments dON d.department_id = e.department_id ON d.department_id = e.department_id ON d.department_id = e.department_id ON d.department_id = e.department_id JOIN locations lJOIN locations lJOIN locations lJOIN locations lON d.location_id = l.location_id;ON d.location_id = l.location_id;ON d.location_id = l.location_id;ON d.location_id = l.location_id;

…………

5-31 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

INNERINNERINNERINNER 连接与OUTEROUTEROUTEROUTER 连接的对比

• 在SQL: 1999SQL: 1999SQL: 1999SQL: 1999中, , , , 两个表的连接只返回匹配行的被叫做内连接....

• 两个表的连接结果既包括了内连接,又包括了不匹配左(右)边表的结果集,也就是左(右)外连接....

• 两个表的连接结果既包含了内连接的结果,也包含了左右外连接的结果,被叫做完全连接....

5-32 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameFROM employees eFROM employees eFROM employees eFROM employees eLEFT OUTER JOIN departments dLEFT OUTER JOIN departments dLEFT OUTER JOIN departments dLEFT OUTER JOIN departments dON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;

左外连接

…………

5-33 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameFROM employees eFROM employees eFROM employees eFROM employees eRIGHT OUTER JOIN departments dRIGHT OUTER JOIN departments dRIGHT OUTER JOIN departments dRIGHT OUTER JOIN departments dON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;

右外连接

…………

5-34 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameFROM employees eFROM employees eFROM employees eFROM employees eFULL OUTER JOIN departments dFULL OUTER JOIN departments dFULL OUTER JOIN departments dFULL OUTER JOIN departments dON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;

完全外连接

…………

注意完全外连接的执行顺序?

5-35 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_idFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dON (e.department_id = d.department_id)ON (e.department_id = d.department_id)ON (e.department_id = d.department_id)ON (e.department_id = d.department_id)AND e.manager_id = 149 ;AND e.manager_id = 149 ;AND e.manager_id = 149 ;AND e.manager_id = 149 ;

增加其他的查询条件

5-36 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Types of JoinsTypes of JoinsTypes of JoinsTypes of Joins

Joins that are compliant with the SQL:1999 standard Joins that are compliant with the SQL:1999 standard Joins that are compliant with the SQL:1999 standard Joins that are compliant with the SQL:1999 standard include the following:include the following:include the following:include the following:• Cross joinsCross joinsCross joinsCross joins• Natural joinsNatural joinsNatural joinsNatural joins• USINGUSINGUSINGUSING clause clause clause clause• Full (or two-sided) outer joinsFull (or two-sided) outer joinsFull (or two-sided) outer joinsFull (or two-sided) outer joins• Arbitrary join conditions for outer joinsArbitrary join conditions for outer joinsArbitrary join conditions for outer joinsArbitrary join conditions for outer joins

5-37 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Joining Tables Using SQL:1999 SyntaxJoining Tables Using SQL:1999 SyntaxJoining Tables Using SQL:1999 SyntaxJoining Tables Using SQL:1999 Syntax

Use a join to query data from more than one table:Use a join to query data from more than one table:Use a join to query data from more than one table:Use a join to query data from more than one table:

SELECTSELECTSELECTSELECT table1.column, table2.columntable1.column, table2.columntable1.column, table2.columntable1.column, table2.columnFROMFROMFROMFROM table1table1table1table1[NATURAL JOIN [NATURAL JOIN [NATURAL JOIN [NATURAL JOIN table2table2table2table2] |] |] |] |[JOIN [JOIN [JOIN [JOIN table2table2table2table2 USING ( USING ( USING ( USING (column_namecolumn_namecolumn_namecolumn_name)] |)] |)] |)] |[JOIN [JOIN [JOIN [JOIN table2table2table2table2 ON ( ON ( ON ( ON (table1.column_nametable1.column_nametable1.column_nametable1.column_name = = = = table2.column_nametable2.column_nametable2.column_nametable2.column_name)]|)]|)]|)]|[LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN [LEFT|RIGHT|FULL OUTER JOIN table2table2table2table2 ON ( ON ( ON ( ON (table1.column_nametable1.column_nametable1.column_nametable1.column_name = = = = table2.column_nametable2.column_nametable2.column_nametable2.column_name)]|)]|)]|)]|[CROSS JOIN [CROSS JOIN [CROSS JOIN [CROSS JOIN table2table2table2table2];];];];

5-38 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Creating Natural JoinsCreating Natural JoinsCreating Natural JoinsCreating Natural Joins

• The The The The NATURALNATURALNATURALNATURAL JOINJOINJOINJOIN clause is based on all columns clause is based on all columns clause is based on all columns clause is based on all columns in the two tables that have the same name.in the two tables that have the same name.in the two tables that have the same name.in the two tables that have the same name.

• It selects rows from the two tables that have equal It selects rows from the two tables that have equal It selects rows from the two tables that have equal It selects rows from the two tables that have equal values in all matched columns.values in all matched columns.values in all matched columns.values in all matched columns.

• If the columns having the same names have If the columns having the same names have If the columns having the same names have If the columns having the same names have different data types, an error is returned.different data types, an error is returned.different data types, an error is returned.different data types, an error is returned.

5-39 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT department_id, department_name,SELECT department_id, department_name,SELECT department_id, department_name,SELECT department_id, department_name, location_id, city location_id, city location_id, city location_id, cityFROM departmentsFROM departmentsFROM departmentsFROM departmentsNATURAL JOIN locations ;NATURAL JOIN locations ;NATURAL JOIN locations ;NATURAL JOIN locations ;

Retrieving Records with Natural JoinsRetrieving Records with Natural JoinsRetrieving Records with Natural JoinsRetrieving Records with Natural Joins

5-40 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Creating Joins with the Creating Joins with the Creating Joins with the Creating Joins with the USINGUSINGUSINGUSING Clause Clause Clause Clause

• If several columns have the same names but the If several columns have the same names but the If several columns have the same names but the If several columns have the same names but the data types do not match, the data types do not match, the data types do not match, the data types do not match, the NATURALNATURALNATURALNATURAL JOINJOINJOINJOIN clause clause clause clause can be modified with the can be modified with the can be modified with the can be modified with the USINGUSINGUSINGUSING clause to specify clause to specify clause to specify clause to specify the columns that should be used for an equijoin.the columns that should be used for an equijoin.the columns that should be used for an equijoin.the columns that should be used for an equijoin.

• Use the Use the Use the Use the USINGUSINGUSINGUSING clause to match only one column clause to match only one column clause to match only one column clause to match only one column when more than one column matches.when more than one column matches.when more than one column matches.when more than one column matches.

• Do not use a table name or alias in the referenced Do not use a table name or alias in the referenced Do not use a table name or alias in the referenced Do not use a table name or alias in the referenced columns.columns.columns.columns.

• The The The The NATURALNATURALNATURALNATURAL JOINJOINJOINJOIN and and and and USINGUSINGUSINGUSING clauses are clauses are clauses are clauses are mutually exclusive.mutually exclusive.mutually exclusive.mutually exclusive.

5-41 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Joining Column NamesJoining Column NamesJoining Column NamesJoining Column Names

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES DEPARTMENTS DEPARTMENTS DEPARTMENTS DEPARTMENTS

Foreign keyForeign keyForeign keyForeign key Primary keyPrimary keyPrimary keyPrimary key

………… …………

5-42 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, SELECT employees.employee_id, employees.last_name, departments.location_id, department_id departments.location_id, department_id departments.location_id, department_id departments.location_id, department_idFROM employees JOIN departmentsFROM employees JOIN departmentsFROM employees JOIN departmentsFROM employees JOIN departmentsUSING (department_id) ;USING (department_id) ;USING (department_id) ;USING (department_id) ;

Retrieving Records with the Retrieving Records with the Retrieving Records with the Retrieving Records with the USINGUSINGUSINGUSING Clause Clause Clause Clause

…………

5-43 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Qualifying Ambiguous Qualifying Ambiguous Qualifying Ambiguous Qualifying Ambiguous Column NamesColumn NamesColumn NamesColumn Names

• Use table prefixes to qualify column names that Use table prefixes to qualify column names that Use table prefixes to qualify column names that Use table prefixes to qualify column names that are in multiple tables.are in multiple tables.are in multiple tables.are in multiple tables.

• Use table prefixes to improve performance.Use table prefixes to improve performance.Use table prefixes to improve performance.Use table prefixes to improve performance.• Use column aliases to distinguish columns that Use column aliases to distinguish columns that Use column aliases to distinguish columns that Use column aliases to distinguish columns that

have identical names but reside in different tables.have identical names but reside in different tables.have identical names but reside in different tables.have identical names but reside in different tables.• Do not use aliases on columns that are identified Do not use aliases on columns that are identified Do not use aliases on columns that are identified Do not use aliases on columns that are identified

in the in the in the in the USINGUSINGUSINGUSING clause and listed elsewhere in the clause and listed elsewhere in the clause and listed elsewhere in the clause and listed elsewhere in the SQL statement.SQL statement.SQL statement.SQL statement.

5-44 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.employee_id, e.last_name, SELECT e.employee_id, e.last_name, SELECT e.employee_id, e.last_name, SELECT e.employee_id, e.last_name, d.location_id, department_id d.location_id, department_id d.location_id, department_id d.location_id, department_idFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dUSING (department_id) ;USING (department_id) ;USING (department_id) ;USING (department_id) ;

Using Table AliasesUsing Table AliasesUsing Table AliasesUsing Table Aliases

• Use table aliases to simplify queries.Use table aliases to simplify queries.Use table aliases to simplify queries.Use table aliases to simplify queries.• Use table aliases to improve performance.Use table aliases to improve performance.Use table aliases to improve performance.Use table aliases to improve performance.

5-45 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Creating Joins with the Creating Joins with the Creating Joins with the Creating Joins with the ONONONON Clause Clause Clause Clause

• The join condition for the natural join is basically The join condition for the natural join is basically The join condition for the natural join is basically The join condition for the natural join is basically an equijoin of all columns with the same name.an equijoin of all columns with the same name.an equijoin of all columns with the same name.an equijoin of all columns with the same name.

• Use the Use the Use the Use the ONONONON clause to specify arbitrary conditions clause to specify arbitrary conditions clause to specify arbitrary conditions clause to specify arbitrary conditions or specify columns to join.or specify columns to join.or specify columns to join.or specify columns to join.

• The join condition is separated from other search The join condition is separated from other search The join condition is separated from other search The join condition is separated from other search conditions.conditions.conditions.conditions.

• The The The The ONONONON clause makes code easy to understand. clause makes code easy to understand. clause makes code easy to understand. clause makes code easy to understand.

5-46 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_idFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dON (e.department_id = d.department_id);ON (e.department_id = d.department_id);ON (e.department_id = d.department_id);ON (e.department_id = d.department_id);

Retrieving Records with the Retrieving Records with the Retrieving Records with the Retrieving Records with the ONONONON Clause Clause Clause Clause

…………

5-47 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Self-Joins Using the Self-Joins Using the Self-Joins Using the Self-Joins Using the ONONONON Clause Clause Clause Clause

MANAGER_IDMANAGER_IDMANAGER_IDMANAGER_ID in the in the in the in the WORKERWORKERWORKERWORKER table is equal to table is equal to table is equal to table is equal to EMPLOYEE_IDEMPLOYEE_IDEMPLOYEE_IDEMPLOYEE_ID in the in the in the in the MANAGERMANAGERMANAGERMANAGER table. table. table. table.

EMPLOYEES (WORKER)EMPLOYEES (WORKER)EMPLOYEES (WORKER)EMPLOYEES (WORKER) EMPLOYEES (MANAGER)EMPLOYEES (MANAGER)EMPLOYEES (MANAGER)EMPLOYEES (MANAGER)

………… …………

5-48 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Self-Joins Using the Self-Joins Using the Self-Joins Using the Self-Joins Using the ONONONON Clause Clause Clause Clause

SELECT e.last_name emp, m.last_name mgrSELECT e.last_name emp, m.last_name mgrSELECT e.last_name emp, m.last_name mgrSELECT e.last_name emp, m.last_name mgrFROM employees e JOIN employees mFROM employees e JOIN employees mFROM employees e JOIN employees mFROM employees e JOIN employees mON (e.manager_id = m.employee_id);ON (e.manager_id = m.employee_id);ON (e.manager_id = m.employee_id);ON (e.manager_id = m.employee_id);

…………

5-49 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_id d.department_id, d.location_idFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dFROM employees e JOIN departments dON (e.department_id = d.department_id)ON (e.department_id = d.department_id)ON (e.department_id = d.department_id)ON (e.department_id = d.department_id)AND e.manager_id = 149 ;AND e.manager_id = 149 ;AND e.manager_id = 149 ;AND e.manager_id = 149 ;

Applying Additional ConditionsApplying Additional ConditionsApplying Additional ConditionsApplying Additional Conditionsto a Jointo a Jointo a Jointo a Join

5-50 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT employee_id, city, department_nameSELECT employee_id, city, department_nameSELECT employee_id, city, department_nameSELECT employee_id, city, department_nameFROM employees e FROM employees e FROM employees e FROM employees e JOIN departments dJOIN departments dJOIN departments dJOIN departments dON d.department_id = e.department_id ON d.department_id = e.department_id ON d.department_id = e.department_id ON d.department_id = e.department_id JOIN locations lJOIN locations lJOIN locations lJOIN locations lON d.location_id = l.location_id;ON d.location_id = l.location_id;ON d.location_id = l.location_id;ON d.location_id = l.location_id;

Creating Three-Way Joins with the Creating Three-Way Joins with the Creating Three-Way Joins with the Creating Three-Way Joins with the ONONONON Clause Clause Clause Clause

…………

5-51 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Non-EquijoinsNon-EquijoinsNon-EquijoinsNon-Equijoins

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES JOB_GRADESJOB_GRADESJOB_GRADESJOB_GRADES

Salary in the Salary in the Salary in the Salary in the EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES table must be between table must be between table must be between table must be between lowest salary and highest lowest salary and highest lowest salary and highest lowest salary and highest salary in the salary in the salary in the salary in the JOB_GRADESJOB_GRADESJOB_GRADESJOB_GRADEStable.table.table.table.

…………

5-52 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.last_name, e.salary, j.grade_levelSELECT e.last_name, e.salary, j.grade_levelSELECT e.last_name, e.salary, j.grade_levelSELECT e.last_name, e.salary, j.grade_levelFROM employees e JOIN job_grades jFROM employees e JOIN job_grades jFROM employees e JOIN job_grades jFROM employees e JOIN job_grades jON e.salary ON e.salary ON e.salary ON e.salary BETWEEN j.lowest_sal AND j.highest_sal; BETWEEN j.lowest_sal AND j.highest_sal; BETWEEN j.lowest_sal AND j.highest_sal; BETWEEN j.lowest_sal AND j.highest_sal;

Retrieving Records Retrieving Records Retrieving Records Retrieving Records with Non-Equijoinswith Non-Equijoinswith Non-Equijoinswith Non-Equijoins

…………

5-53 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Outer JoinsOuter JoinsOuter JoinsOuter Joins

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEESDEPARTMENTSDEPARTMENTSDEPARTMENTSDEPARTMENTS

There are no employees in There are no employees in There are no employees in There are no employees in department 190. department 190. department 190. department 190.

…………

5-54 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

INNERINNERINNERINNER Versus Versus Versus Versus OUTEROUTEROUTEROUTER Joins Joins Joins Joins

• In SQL:1999, the join of two tables returning only In SQL:1999, the join of two tables returning only In SQL:1999, the join of two tables returning only In SQL:1999, the join of two tables returning only matched rows is called an inner join.matched rows is called an inner join.matched rows is called an inner join.matched rows is called an inner join.

• A join between two tables that returns the results A join between two tables that returns the results A join between two tables that returns the results A join between two tables that returns the results of the inner join as well as the unmatched rows of the inner join as well as the unmatched rows of the inner join as well as the unmatched rows of the inner join as well as the unmatched rows from the left (or right) tables is called a left (or from the left (or right) tables is called a left (or from the left (or right) tables is called a left (or from the left (or right) tables is called a left (or right) outer join.right) outer join.right) outer join.right) outer join.

• A join between two tables that returns the results A join between two tables that returns the results A join between two tables that returns the results A join between two tables that returns the results of an inner join as well as the results of a left and of an inner join as well as the results of a left and of an inner join as well as the results of a left and of an inner join as well as the results of a left and right join is a full outer join.right join is a full outer join.right join is a full outer join.right join is a full outer join.

5-55 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameFROM employees e LEFT OUTER JOIN departments dFROM employees e LEFT OUTER JOIN departments dFROM employees e LEFT OUTER JOIN departments dFROM employees e LEFT OUTER JOIN departments dON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;

LEFT OUTER JOINLEFT OUTER JOINLEFT OUTER JOINLEFT OUTER JOIN

…………

5-56 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameSELECT e.last_name, e.department_id, d.department_nameFROM employees e RIGHT OUTER JOIN departments dFROM employees e RIGHT OUTER JOIN departments dFROM employees e RIGHT OUTER JOIN departments dFROM employees e RIGHT OUTER JOIN departments dON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;

RIGHT OUTER JOINRIGHT OUTER JOINRIGHT OUTER JOINRIGHT OUTER JOIN

…………

5-57 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT e.last_name, d.department_id, d.department_nameSELECT e.last_name, d.department_id, d.department_nameSELECT e.last_name, d.department_id, d.department_nameSELECT e.last_name, d.department_id, d.department_nameFROM employees e FULL OUTER JOIN departments dFROM employees e FULL OUTER JOIN departments dFROM employees e FULL OUTER JOIN departments dFROM employees e FULL OUTER JOIN departments dON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;ON (e.department_id = d.department_id) ;

FULL OUTER JOINFULL OUTER JOINFULL OUTER JOINFULL OUTER JOIN

…………

5-58 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Cartesian ProductsCartesian ProductsCartesian ProductsCartesian Products

• A Cartesian product is formed when:A Cartesian product is formed when:A Cartesian product is formed when:A Cartesian product is formed when:– A join condition is omittedA join condition is omittedA join condition is omittedA join condition is omitted– A join condition is invalidA join condition is invalidA join condition is invalidA join condition is invalid– All rows in the first table are joined to all rows in the All rows in the first table are joined to all rows in the All rows in the first table are joined to all rows in the All rows in the first table are joined to all rows in the

second tablesecond tablesecond tablesecond table• To avoid a Cartesian product, always include a To avoid a Cartesian product, always include a To avoid a Cartesian product, always include a To avoid a Cartesian product, always include a

valid join condition.valid join condition.valid join condition.valid join condition.

5-59 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Generating a Cartesian ProductGenerating a Cartesian ProductGenerating a Cartesian ProductGenerating a Cartesian Product

Cartesian product: Cartesian product: Cartesian product: Cartesian product: 20 x 8 = 160 rows20 x 8 = 160 rows20 x 8 = 160 rows20 x 8 = 160 rows

EMPLOYEESEMPLOYEESEMPLOYEESEMPLOYEES (20 rows)(20 rows)(20 rows)(20 rows) DEPARTMENTSDEPARTMENTSDEPARTMENTSDEPARTMENTS (8 rows)(8 rows)(8 rows)(8 rows)

…………

…………

5-60 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SELECT last_name, department_nameSELECT last_name, department_nameSELECT last_name, department_nameSELECT last_name, department_nameFROM employeesFROM employeesFROM employeesFROM employeesCROSS JOIN departments ;CROSS JOIN departments ;CROSS JOIN departments ;CROSS JOIN departments ;

Creating Cross JoinsCreating Cross JoinsCreating Cross JoinsCreating Cross Joins

• The The The The CROSSCROSSCROSSCROSS JOINJOINJOINJOIN clause produces the cross- clause produces the cross- clause produces the cross- clause produces the cross-product of two tables. product of two tables. product of two tables. product of two tables.

• This is also called a Cartesian product between This is also called a Cartesian product between This is also called a Cartesian product between This is also called a Cartesian product between the two tables. the two tables. the two tables. the two tables.

…………

5-61 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

SummarySummarySummarySummary

In this lesson, you should have learned how to use In this lesson, you should have learned how to use In this lesson, you should have learned how to use In this lesson, you should have learned how to use joins to display data from multiple tables by using:joins to display data from multiple tables by using:joins to display data from multiple tables by using:joins to display data from multiple tables by using:• EquijoinsEquijoinsEquijoinsEquijoins• Non-equijoinsNon-equijoinsNon-equijoinsNon-equijoins• Outer joinsOuter joinsOuter joinsOuter joins• Self-joinsSelf-joinsSelf-joinsSelf-joins• Cross joinsCross joinsCross joinsCross joins• Natural joinsNatural joinsNatural joinsNatural joins• Full (or two-sided) outer joinsFull (or two-sided) outer joinsFull (or two-sided) outer joinsFull (or two-sided) outer joins

5-62 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice 5: OverviewPractice 5: OverviewPractice 5: OverviewPractice 5: Overview

This practice covers the following topics:This practice covers the following topics:This practice covers the following topics:This practice covers the following topics:• Joining tables using an equijoinJoining tables using an equijoinJoining tables using an equijoinJoining tables using an equijoin• Performing outer and self-joinsPerforming outer and self-joinsPerforming outer and self-joinsPerforming outer and self-joins• Adding conditionsAdding conditionsAdding conditionsAdding conditions

5-63 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q1:Q1:Q1:Q1:Click the Exhibit button to examine the structures of Click the Exhibit button to examine the structures of Click the Exhibit button to examine the structures of Click the Exhibit button to examine the structures of the EMPLOYEES, DEPARTMENTS, and TAX tables. the EMPLOYEES, DEPARTMENTS, and TAX tables. the EMPLOYEES, DEPARTMENTS, and TAX tables. the EMPLOYEES, DEPARTMENTS, and TAX tables.

5-64 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555Q1: Q1: Q1: Q1: For which situation would you use a nonequijoin query? For which situation would you use a nonequijoin query? For which situation would you use a nonequijoin query? For which situation would you use a nonequijoin query?

AAAA. to find the tax percentage for each of the employees . to find the tax percentage for each of the employees . to find the tax percentage for each of the employees . to find the tax percentage for each of the employees

B. to list the name, job_id, and manager name for all the B. to list the name, job_id, and manager name for all the B. to list the name, job_id, and manager name for all the B. to list the name, job_id, and manager name for all the employees employees employees employees

C. to find the name, salary, and the department name of C. to find the name, salary, and the department name of C. to find the name, salary, and the department name of C. to find the name, salary, and the department name of employees who are not working with Smith employees who are not working with Smith employees who are not working with Smith employees who are not working with Smith

D. to find the number of employees working for the D. to find the number of employees working for the D. to find the number of employees working for the D. to find the number of employees working for the Administrative department and earning less than 4000 Administrative department and earning less than 4000 Administrative department and earning less than 4000 Administrative department and earning less than 4000

E. to display name, salary, manager ID, and department name E. to display name, salary, manager ID, and department name E. to display name, salary, manager ID, and department name E. to display name, salary, manager ID, and department name of all the employees, even if the employees do of all the employees, even if the employees do of all the employees, even if the employees do of all the employees, even if the employees do not have a department ID assigned not have a department ID assigned not have a department ID assigned not have a department ID assigned

5-65 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q2:Q2:Q2:Q2:Click the Exhibit button to examine the structures of Click the Exhibit button to examine the structures of Click the Exhibit button to examine the structures of Click the Exhibit button to examine the structures of the EMPLOYEES and TAX tables. the EMPLOYEES and TAX tables. the EMPLOYEES and TAX tables. the EMPLOYEES and TAX tables.

5-66 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555Q2: Q2: Q2: Q2: You need to find the percentage tax applicable for You need to find the percentage tax applicable for You need to find the percentage tax applicable for You need to find the percentage tax applicable for each employee. Which SQL statement would you use?each employee. Which SQL statement would you use?each employee. Which SQL statement would you use?each employee. Which SQL statement would you use?

AAAA. SELECT employee_id, salary, tax_percent . SELECT employee_id, salary, tax_percent . SELECT employee_id, salary, tax_percent . SELECT employee_id, salary, tax_percent FROM employees e JOIN tax t FROM employees e JOIN tax t FROM employees e JOIN tax t FROM employees e JOIN tax t ON e.salary BETWEEN t.min_salary AND t.max_salary; ON e.salary BETWEEN t.min_salary AND t.max_salary; ON e.salary BETWEEN t.min_salary AND t.max_salary; ON e.salary BETWEEN t.min_salary AND t.max_salary;

B. SELECT employee_id, salary, tax_percent B. SELECT employee_id, salary, tax_percent B. SELECT employee_id, salary, tax_percent B. SELECT employee_id, salary, tax_percent FROM employees e JOIN tax t FROM employees e JOIN tax t FROM employees e JOIN tax t FROM employees e JOIN tax t WHERE e.salary > t.min_salary AND < t.max_salary; WHERE e.salary > t.min_salary AND < t.max_salary; WHERE e.salary > t.min_salary AND < t.max_salary; WHERE e.salary > t.min_salary AND < t.max_salary;

C. SELECT employee_id, salary, tax_percent C. SELECT employee_id, salary, tax_percent C. SELECT employee_id, salary, tax_percent C. SELECT employee_id, salary, tax_percent FROM employees e JOIN tax t FROM employees e JOIN tax t FROM employees e JOIN tax t FROM employees e JOIN tax t ON (MIN(e.salary) = t.min_salary ON (MIN(e.salary) = t.min_salary ON (MIN(e.salary) = t.min_salary ON (MIN(e.salary) = t.min_salary AND MAX(e.salary) = t.max_salary); AND MAX(e.salary) = t.max_salary); AND MAX(e.salary) = t.max_salary); AND MAX(e.salary) = t.max_salary);

D. You cannot find the information because there is no D. You cannot find the information because there is no D. You cannot find the information because there is no D. You cannot find the information because there is no common column between the two tables. common column between the two tables. common column between the two tables. common column between the two tables.

5-67 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q3:Q3:Q3:Q3:Examine the structure of the EMPLOYEES and Examine the structure of the EMPLOYEES and Examine the structure of the EMPLOYEES and Examine the structure of the EMPLOYEES and DEPARTMENTS tables: DEPARTMENTS tables: DEPARTMENTS tables: DEPARTMENTS tables:

5-68 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q3:Q3:Q3:Q3:You want to create a report displaying You want to create a report displaying You want to create a report displaying You want to create a report displaying employee last names, department names, and employee last names, department names, and employee last names, department names, and employee last names, department names, and locations. Which query should you use? locations. Which query should you use? locations. Which query should you use? locations. Which query should you use? A. SELECT e.last_name, d. department_name, d.location_id A. SELECT e.last_name, d. department_name, d.location_id A. SELECT e.last_name, d. department_name, d.location_id A. SELECT e.last_name, d. department_name, d.location_id FROM employees e NATURAL JOIN departments D FROM employees e NATURAL JOIN departments D FROM employees e NATURAL JOIN departments D FROM employees e NATURAL JOIN departments D USING department_id ; USING department_id ; USING department_id ; USING department_id ;

B. SELECT last_name, department_name, location_id B. SELECT last_name, department_name, location_id B. SELECT last_name, department_name, location_id B. SELECT last_name, department_name, location_id FROM employees NATURAL JOIN departments FROM employees NATURAL JOIN departments FROM employees NATURAL JOIN departments FROM employees NATURAL JOIN departments WHERE e.department_id =d.department_id; WHERE e.department_id =d.department_id; WHERE e.department_id =d.department_id; WHERE e.department_id =d.department_id;

C. SELECT e.last_name, d.department_name, d.location_id C. SELECT e.last_name, d.department_name, d.location_id C. SELECT e.last_name, d.department_name, d.location_id C. SELECT e.last_name, d.department_name, d.location_id FROM employees e NATURAL JOIN departments d; FROM employees e NATURAL JOIN departments d; FROM employees e NATURAL JOIN departments d; FROM employees e NATURAL JOIN departments d;

DDDD. SELECT e.last_name, d.department_name, d.location_id . SELECT e.last_name, d.department_name, d.location_id . SELECT e.last_name, d.department_name, d.location_id . SELECT e.last_name, d.department_name, d.location_id FROM employees e JOIN departments d USING (department_id ); FROM employees e JOIN departments d USING (department_id ); FROM employees e JOIN departments d USING (department_id ); FROM employees e JOIN departments d USING (department_id );

5-69 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q4Q4Q4Q4::::Click the Exhibit button to examine the structure of the Click the Exhibit button to examine the structure of the Click the Exhibit button to examine the structure of the Click the Exhibit button to examine the structure of the EMPLOYEES, DEPARTMENTS, and LOCATIONS EMPLOYEES, DEPARTMENTS, and LOCATIONS EMPLOYEES, DEPARTMENTS, and LOCATIONS EMPLOYEES, DEPARTMENTS, and LOCATIONS ttttables. ables. ables. ables.

Two new departments are added to your company as shown: Two new departments are added to your company as shown: Two new departments are added to your company as shown: Two new departments are added to your company as shown: DEPARTMENT_ID DEPARTMENT_NAME MGR_ID LOCATION_ID DEPARTMENT_ID DEPARTMENT_NAME MGR_ID LOCATION_ID DEPARTMENT_ID DEPARTMENT_NAME MGR_ID LOCATION_ID DEPARTMENT_ID DEPARTMENT_NAME MGR_ID LOCATION_ID 9998 Engineering 9998 Engineering 9998 Engineering 9998 Engineering 123 123 123 123 9999 Administrative Boston 9999 Administrative Boston 9999 Administrative Boston 9999 Administrative Boston You need to list the names of employees, the department IDs, the You need to list the names of employees, the department IDs, the You need to list the names of employees, the department IDs, the You need to list the names of employees, the department IDs, the department names, and the cities where the departments are, even if department names, and the cities where the departments are, even if department names, and the cities where the departments are, even if department names, and the cities where the departments are, even if there are no employees in the departments and even if the there are no employees in the departments and even if the there are no employees in the departments and even if the there are no employees in the departments and even if the departments are not yet assigned to a location. You need to join the departments are not yet assigned to a location. You need to join the departments are not yet assigned to a location. You need to join the departments are not yet assigned to a location. You need to join the EMPLOYEES, DEPARTMENTS, and LOCATIONS tables to retrieve this EMPLOYEES, DEPARTMENTS, and LOCATIONS tables to retrieve this EMPLOYEES, DEPARTMENTS, and LOCATIONS tables to retrieve this EMPLOYEES, DEPARTMENTS, and LOCATIONS tables to retrieve this information. information. information. information.

Which statement do you execute to retrieve this information? Which statement do you execute to retrieve this information? Which statement do you execute to retrieve this information? Which statement do you execute to retrieve this information?

5-70 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q4:Q4:Q4:Q4:

5-71 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555A. SELECT e.last_name, d.department_id, d.department_name, A. SELECT e.last_name, d.department_id, d.department_name, A. SELECT e.last_name, d.department_id, d.department_name, A. SELECT e.last_name, d.department_id, d.department_name, l.city FROM departments d RIGHT OUTER JOIN employees e ON l.city FROM departments d RIGHT OUTER JOIN employees e ON l.city FROM departments d RIGHT OUTER JOIN employees e ON l.city FROM departments d RIGHT OUTER JOIN employees e ON d.department_id = e.department_id RIGHT OUTER JOIN locations l d.department_id = e.department_id RIGHT OUTER JOIN locations l d.department_id = e.department_id RIGHT OUTER JOIN locations l d.department_id = e.department_id RIGHT OUTER JOIN locations l ON d.location_id = l.location_id; ON d.location_id = l.location_id; ON d.location_id = l.location_id; ON d.location_id = l.location_id;

B. SELECT e.last_name, d.department_id, d.department_name, B. SELECT e.last_name, d.department_id, d.department_name, B. SELECT e.last_name, d.department_id, d.department_name, B. SELECT e.last_name, d.department_id, d.department_name, l.city FROM departments d FULL OUTER JOIN employees e l.city FROM departments d FULL OUTER JOIN employees e l.city FROM departments d FULL OUTER JOIN employees e l.city FROM departments d FULL OUTER JOIN employees e ON d.department_id = e.department_id FULL OUTER JOIN ON d.department_id = e.department_id FULL OUTER JOIN ON d.department_id = e.department_id FULL OUTER JOIN ON d.department_id = e.department_id FULL OUTER JOIN locations l ON d.location_id = l.location_id; locations l ON d.location_id = l.location_id; locations l ON d.location_id = l.location_id; locations l ON d.location_id = l.location_id;

CCCC. SELECT e.last_name, d.department_id, d.department_name, . SELECT e.last_name, d.department_id, d.department_name, . SELECT e.last_name, d.department_id, d.department_name, . SELECT e.last_name, d.department_id, d.department_name, l.city FROM departments d LEFT OUTER JOIN employees e l.city FROM departments d LEFT OUTER JOIN employees e l.city FROM departments d LEFT OUTER JOIN employees e l.city FROM departments d LEFT OUTER JOIN employees e ON d.department_id = e.department_id LEFT OUTER JOIN ON d.department_id = e.department_id LEFT OUTER JOIN ON d.department_id = e.department_id LEFT OUTER JOIN ON d.department_id = e.department_id LEFT OUTER JOIN locations l ON d.location_id = l.location_id; locations l ON d.location_id = l.location_id; locations l ON d.location_id = l.location_id; locations l ON d.location_id = l.location_id;

D. SELECT last_name, department_id, department_name, city D. SELECT last_name, department_id, department_name, city D. SELECT last_name, department_id, department_name, city D. SELECT last_name, department_id, department_name, city FROM departments d NATURAL JOIN employees e NATURAL FROM departments d NATURAL JOIN employees e NATURAL FROM departments d NATURAL JOIN employees e NATURAL FROM departments d NATURAL JOIN employees e NATURAL JOIN locations l; JOIN locations l; JOIN locations l; JOIN locations l;

5-72 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q5Q5Q5Q5::::Click the Exhibit button and examine the data in the Click the Exhibit button and examine the data in the Click the Exhibit button and examine the data in the Click the Exhibit button and examine the data in the EMPLOYEES and DEPARTMENTS tables. EMPLOYEES and DEPARTMENTS tables. EMPLOYEES and DEPARTMENTS tables. EMPLOYEES and DEPARTMENTS tables.

5-73 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q5Q5Q5Q5::::You want to retrieve all employees' last names, along You want to retrieve all employees' last names, along You want to retrieve all employees' last names, along You want to retrieve all employees' last names, along with their managers' last names and their department with their managers' last names and their department with their managers' last names and their department with their managers' last names and their department names. Which query would you use? names. Which query would you use? names. Which query would you use? names. Which query would you use?

A. SELECT last_name, manager_id, department_name FROM employees e A. SELECT last_name, manager_id, department_name FROM employees e A. SELECT last_name, manager_id, department_name FROM employees e A. SELECT last_name, manager_id, department_name FROM employees e FULL OUTER JOIN departments d ON (e.department_id = d.department_id);FULL OUTER JOIN departments d ON (e.department_id = d.department_id);FULL OUTER JOIN departments d ON (e.department_id = d.department_id);FULL OUTER JOIN departments d ON (e.department_id = d.department_id); BBBB. SELECT e.last_name, m.last_name, department_name FROM employees . SELECT e.last_name, m.last_name, department_name FROM employees . SELECT e.last_name, m.last_name, department_name FROM employees . SELECT e.last_name, m.last_name, department_name FROM employees e LEFT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e LEFT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e LEFT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e LEFT OUTER JOIN employees m on ( e.manager_id = m.employee_id) LEFT OUTER JOIN departments d ON (e.department_id = d.department_id); LEFT OUTER JOIN departments d ON (e.department_id = d.department_id); LEFT OUTER JOIN departments d ON (e.department_id = d.department_id); LEFT OUTER JOIN departments d ON (e.department_id = d.department_id);

C. SELECT e.last_name, m.last_name, department_name FROM employees C. SELECT e.last_name, m.last_name, department_name FROM employees C. SELECT e.last_name, m.last_name, department_name FROM employees C. SELECT e.last_name, m.last_name, department_name FROM employees e RIGHT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e RIGHT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e RIGHT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e RIGHT OUTER JOIN employees m on ( e.manager_id = m.employee_id) LEFT OUTER JOIN departments d ON (e.department_id = d.department_id); LEFT OUTER JOIN departments d ON (e.department_id = d.department_id); LEFT OUTER JOIN departments d ON (e.department_id = d.department_id); LEFT OUTER JOIN departments d ON (e.department_id = d.department_id);

5-74 Copyright © 2012, http://OracleOnLinux.cn. Part rights reserved.

Practice Practice Practice Practice 5555

Q5Q5Q5Q5::::

D. SELECT e.last_name, m.last_name, department_name FROM employees D. SELECT e.last_name, m.last_name, department_name FROM employees D. SELECT e.last_name, m.last_name, department_name FROM employees D. SELECT e.last_name, m.last_name, department_name FROM employees e LEFT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e LEFT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e LEFT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e LEFT OUTER JOIN employees m on ( e.manager_id = m.employee_id) RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id);RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id);RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id);RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id); E. SELECT e.last_name, m.last_name, department_name FROM employees E. SELECT e.last_name, m.last_name, department_name FROM employees E. SELECT e.last_name, m.last_name, department_name FROM employees E. SELECT e.last_name, m.last_name, department_name FROM employees e RIGHT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e RIGHT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e RIGHT OUTER JOIN employees m on ( e.manager_id = m.employee_id) e RIGHT OUTER JOIN employees m on ( e.manager_id = m.employee_id) RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id);RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id);RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id);RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id); F. SELECT last_name, manager_id, department_name FROM employees e F. SELECT last_name, manager_id, department_name FROM employees e F. SELECT last_name, manager_id, department_name FROM employees e F. SELECT last_name, manager_id, department_name FROM employees e JOIN departments d ON (e.department_id = d.department_id) ; JOIN departments d ON (e.department_id = d.department_id) ; JOIN departments d ON (e.department_id = d.department_id) ; JOIN departments d ON (e.department_id = d.department_id) ;