【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--非自连接
    --自连接

--外连接
    --左外连接、右外连接、满外连接

 

posted @ 2020-05-15 11:46  emdzz  阅读(194)  评论(0)    收藏  举报