二、Sql99:不需要一次性把所有需要连接的表放在from后, 而是采用JOIN方式, 每次连接一张表
select 查询列表 from 表1 别名 【连接类型】 join 表2 别名 on 连接条件 【where 筛选条件】 【group by 分组】 【having 筛选条件】 【order by 排序列表】 |
连接类型:
内连接:inner
外连接:左外 left 【outer】
右外 right 【outer】
全外 full 【outer】
交叉连接:cross
|
- 内连接:
- 根据连接条件:(1)表1有而表2没有或表1没有而表2有的部分,均删除。
(2)表1有1而表2有n或表1有n而表2有1,按对应关系补齐n条记录 - 根据连接条件,若表1一条记录对应n条表2记录,则生成n条新记录,而不是删除多余的表2的记录
外连接:
- 以主表记录为准,连接从表记录,根据连接条件:(1)主表有从表没有,从表字段填充为null;(内连接与外连接的唯一区别)(2)主表没有从表有的部分,删除。
(3)主表有1而从表有n或主表有n而从表有1,按对应关系补齐n条记录 - left join左边的是主表,right join右边的是主表; 注:内连接无left和right的区分,因为无主从表之分。
(一) 内连接
(1)等值连接(Inner可以省略) /**案例1:查询员工名、部门名**/ SELECT last_name,department_name FROM employees e INNER JOIN departments d ON e.department_id = d.department_id; /**案例2:查询名字中包含e的员工名和工种名(添加筛选)**/ SELECT last_name,job_title FROM employees e INNER JOIN jobs j ON e.job_id = j.job_id WHERE last_name LIKE ‘%e%’; /**案例3:查询部门个数>3的城市名和部门个数(分组+筛选) (先查询每个城市的部门个数-筛选满足条件的部门)**/ SELECT city,count(*) 部门个数 FROM locations l INNER JOIN departments d ON l.location_id = d.location_id GROUP BY city HAVING 部门个数>3; /**案例4:查询哪个部门的部门员工个数>3的部门名称和员工个数,并按照个数降序排序**/ SELECT department_name,count(*) 员工个数 FROM employees e INNER JOIN departments d ON e.department_id = d.department_id GROUP BY department_name HAVING 员工个数>3 ORDER BY 员工个数 DESC; /**案例5:查询员工名、部门名、工种名并按照部门名降序**/ SELECT last_name,department_name,job_title FROM employees e INNER JOIN departments d ON e.department_id = d.department_id INNER JOIN jobs j ON e.job_id = j.job_id ORDER BY department_name DESC; |
(2)非等值连接 /**案例1:查询员工的工资级别**/ SELECT salary,grade_level FROM employees e JOIN job_grade jg ON e.salary BETWEEN jg.lowest_sal AND jg.highest_sal; /**案例2:查询每个工资级别的个数,并且按照个数的降序排序**/ SELECT grade_level,count(*) 个数 FROM employees e JOIN job_grade jg ON e.salary BETWEEN jg.lowest_sal AND jg.highest_sal; ORDER BY 个数 DESC; (3)自连接 /**案例1:查询员工的名字、上级的名字**/ SELECT e.last_name,m.last_name FROM employees e JOIN employee m ON e.’manager_id’ = m.’employee_id’; /**案例1:查询员工的名字包含k、上级的名字**/ SELECT e.last_name,m.last_name FROM employees e JOIN employee m ON e.manager_id = m.employee_id WHERE e.last_name LIKE ‘%K%’; |
(二)外连接:用于查询一个表中有,另一个表中没有的数据
查询结果为主表中的所有记录 + (1)从表中和它匹配的数据 (2)若从表中没有相匹配的数据,则显示为null
/**案例1:查询男朋友不在男神表的女神名(使用左外连接)**/ SELECT bea.name FROM beauty bea LEFT OUTER JOIN boys b ON bea.boyfriend_id = b.’id’ WHERE b.id IS NULL; |
/**案例2:查询男朋友不在男神表的女神名(使用右外连接)**/ SELECT bea.name FROM boys b RIGHT OUTER JOIN beauty bea ON b.id = bea.boyfriend_id WHERE b.id IS NULL; |
/**案例3:查询哪个部门没有员工 (首先考虑哪个是主表:由于查询的是部门信息,因此departments为主表)**/ SELECT d.*,e.employee_id FROM departments d LEFT OUTER JOIN employees e ON d.department_id = e.department_id WHERE e.employee_id IS NULL; |
(三)全外连接:查询结果 = 内连接的结果 + 表1但表2中没有的+表2有单表1中没有的,sql不支持
(四)交叉连接:即使用sq l99语法的标准来实现笛卡尔乘积的效果 CROSS JOIN