MySQL4

文章目录

      • 为什么需要多表的查询
      • 笛卡尔积的错误与正确的多表查询
      • 等值连接vs非等值连接,自连接vs非自连接
      • 语法如何实现内连接和外连接

为什么需要多表的查询

目前所学查询语句:
SELECT …
FROM …
WHERE …AND /OR /NOT
ORDER BY … (ASC /DESC) ,…,…
LIMIT …,…

# 1.熟悉常见的几个表  DESC 查看表信息
DESC employees;
DESC departments;
DESC locations;

#查询员工名为'Abel'在哪个城市工作?
SELECT  *
FROM employees
WHERE  last_name='Abel';

SELECT *
FROM departments;
WHERE departmeny_id=80;

SELECT *
FROM loctions
WHERE loction_id=2500;

笛卡尔积的错误与正确的多表查询

笛卡尔积(交叉链接)的理解
笛卡尔积是一个数学运算,假设我有两个集合X和Y,那么X和Y的笛卡尔积就是X和Y的所有的组合。(两个集合中元素的个数的乘积)

笛卡尔积的错误在下面条件产生:

  • 省略多个表的连接条件(或者关联条件)
  • 连接条件(或者关联条件)失效
  • 所有表中的所有行互相连接
#出现笛卡尔积的错误
#错误原因:缺少了多表的连接条件

#错误的实现方式:每个员工都与每个部门匹配了一遍
SELECT  employee_id,,department_name
FROM  employees  ,departments;  #查询出来2889条记录

#错误的方式
SELECT  employee_id,,department_name
FROM  employees  CROSS JOIN departments;  #查询出来2889条记录


SELECT *
FROM employees; #107条记录

SELECT 2889/107
FROM DUAL;

SELECT *
FROM departments; #27条记录

#多表查询的正确方式:需要有连接条件
SELECT  employee_id,,department_name  
FROM  employees  ,departments
#两个表的连接条件,着重号'可加可不加
WHERE  employees,'department_id'=departments.'department_id'; 
#结果106 有个员工的部门号为null,无法匹配

#如果查询语句中出现多个表中都存在的字段,则必须指明此字段所在的表
SELECT  employees.employee_id,departments.department_name  ,employees.department_id
FROM  employees  ,departments
WHERE  employees.'department_id'=departments.'department_id'; 

#建议:从sql优化的角度,建议多表查询时,每个字段前都指明其所在的表

#可以给表起别名,在SELECT和WHERE使用表的别名
SELECT  emp.employee_id,dept.department_name  ,emp.department_id
FROM  employees  emp ,departments dept
WHERE  emp.'department_id'=dept.'department_id'; 

#起了别名,一旦在SELECT 或者WHERE 中使用表名的话,则必须使用表的别名,而不能使用表的原名
#如下的操作是错误的:
SELECT  emp.employee_id,departments.department_name  ,emp.department_id
FROM  employees  emp ,departments dept
WHERE  emp.'department_id'=dept.'department_id'; 

#如果有n个表实现多表的查询,则需要至少n-1个连接条件
#练习:查询员工的employee_id,last_name,department_id,city
SELECT e.employee_id,e.last_name,d.department_id,city,e.department_id
FROM employsees e,departments d,loctions l;
WHERE  e.dapartment_id=d.department_id
AND  d.loction_id=l.loction_id;

等值连接vs非等值连接,自连接vs非自连接

演绎式:提出问题1—> 解决问题1—>提出问题2—> 解决问题2…
归纳式:总–分

多表查询的分类:
角度1:等值连接vs非等值连接
角度2:自连接vs非自连接
角度3:内连接vs外连接

#等值连接vs非等值连接
#非等值连接的例子:
SELECT *
FROM job_grades;

SELECT Last_name,salary,grade_level
FROM employees  e,job_grdes j
# WHERE e.'salary'BETWEEN j.'lowest_sal' AND j.'highest_sal';
WHERE e.'salary'>=j.'lowest_sal' AND  e.'salary'<=j.'highest_sal';

#自连接vs非自连接 自连接:自己连接自己
SELECT * FROM employees;

#自连接的例子:
#练习:查询员工id,姓名以及管理者的id和姓名
SELECT  emp employee_id,last_name,mgr employee_id,last_name
FROM  employees  emp,employees mgr
WHERE  emp.manager_id=mgr.employee_id;

语法如何实现内连接和外连接

#内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另外一个表不匹配的行
SELECT  employee_id,,department_name  
FROM  employees e ,departments d
WHERE  e.'department_id'=d.'department_id';   #只有106条记录

#外连接:合并具有同一列的两个以上的表的行,结果集中除了包含一个表与另外一个表匹配的行,还查询到了左表或者右表中不匹配的行
#外连接的分类:左外连接 、右外连接,满外连接
#左外连接:两个表在连接过程中除了满足连接条件的行以外还返回左表中不满足条件的行
#右外连接:两个表在连接过程中除了满足连接条件的行以外还返回左表中不满足条件的行

#查询所有员工的last_name,department_name信息 (外连接:所有)

SELECT    employee_id,department_name
FROM      employees  e,departments d
WHERE     e.department_id=d.department_id;

你可能感兴趣的:(mysql)