关于northwind
示例数据库
-
查询数据库中的表
show tables;
-
查询表的表属性
desc xxx(表名);
连接查询
1.概述
- 若一个查询同时涉及两个及以上的表,则称之为连接查询。
- 也可以叫做多表查询。
- 使用
join
关键字进行多表连接。
2.分类(按功能)
- 内连接:等值连接、非等值连接、自链接。
- 外连接:左外连接、右外连接、全外连接。
- 交叉连接。
内连接
0.概述
- 多表连接的结果为多表的交集部分。
- n个表连接,至少需要 n-1 个连接条件。
- 多表顺序没有要求,为方便操作一般需要为表起别名。
- 可以搭配之前所有子句使用。
1.等值连接
-
基本概念
- 基于两个或多个表之间的共同列进行匹配。
- 在等值连接中,两个表的列必须具有相同的数据类型,并且通常使用等于操作符 “=” 进行比较。
- NULL 不等于任何值(包括 NULL 本身),因此如果两个表之间的列中有 NULL 值,则它们不会被视为相等。
-
示例
-
查询员工名字、工种编号和工种名称
# 两个里边都有job_id, 所以要指定出来选择哪个 select first_name, e.job_id, job_title from employees as e join jobs as j on e.job_id = j.job_id;
-
加上筛选:查询有提成员工的员工名字、部门名称和提成
select first_name, department_name, commission_pct from employees as e join departments as d on e.department_id = d.department_id where commission_pct is not null;
-
加上分组:查询城市名称和该城市拥有的部门数量,过滤没有部门的城市
select city, count(*) as num from departments as d join locations as l on d.location_id = l.location_id group by city;
-
加上排序:查询每个工种的工种名称和员工人数,并且按员工人数降序排序
select job_title, count(*) as num from employees as e join jobs as j on e.job_id = j.job_id group by job_title order by num desc;
-
多表查询:查询员工名字、部门名称和所在的城市,并按部门名称降序排序
select first_name, department_name, city from employees as e join departments as d on e.department_id = d.department_id join locations as l on d.location_id = l.location_id order by department_name desc;
-
2.非等值连接
-
基本概念
- 基于两个或多个表之间的共同列进行匹配。
- 但是使用的不是等于操作符 “=”,而是其他比较操作符(如大于号 “>”, 小于号 “<” 等)。
- 通常用于需要在两个表之间根据一个范围或者某些条件进行匹配时。
-
示例
-
查询员工的工资和工资级别
select salary, grade_level from employees as e join job_grades as j on e.salary between j.lowest_sal and highest_sal;
-
查询工资级别和该级别的员工人数,不包括人数小于 20 的工资级别
select grade_level, count(*) as num from employees as e join job_grades as g on e.salary between g.lowest_sal and g.highest_sal group by grade_level having num > 20;
-
3.自链接
-
基本概念
- 在同一张表中通过连接相同的列来查询数据的过程。
- 简单来说,就是将一张表看作两张表进行连接操作。
- 通常用于需要比较同一表中不同行之间的数据时,例如查找员工与其经理之间的关系。
- 自连接本质是两个相同的表连接,写代码时视为两个不相同的表连接。
-
示例
-
查询员工编号、员工名字、上司编号和名字
select e.employee_id, e.first_name, m.employee_id as manager_id, m.first_name as manager_name from employees as e join employees as m on e.manager_id = m.employee_id;
-
查询名为 Lisa 的员工,员工编号、其上司编号和名字
select a.employee_id, a.manager_id, b.first_name from employees as a join employees as b on a.manager_id = b.employee_id where a.first_name = 'Lisa';
-
外连接
1.左外连接
-
基本概念
-
可以返回左表中所有行和右表中与之匹配的行。
-
左表中的所有行都会被保留,而右表中只有符合条件的行才会被保留。
-
如果右表中没有匹配的数据,则填充 NULL 值。
-
-
示例
-
查询任职部门名为 sal 和 it 的员工信息(应将部门信息全部保留)
select e.* from departments as d left join employees as e on d.department_id = e.department_id where d.department_name in ('sal', 'it');
-
查询所有员工的名字和所属部门的名称(应将员工名字全部保留)
select first_name, department_name from employees as e left join departments as d on e.department_id = d.department_id;
-
查询所有部门的名称以及该部门的平均工资 average_salary (不要小数部分),并按平均工资降序排序。(应将部门名称全部保留)
select department_name, truncate(avg(salary), 0) as average_salary from departments as d left join employees as e on d.department_id = e.department_id group by department_name order by average_salary desc;
-
2.右外连接
-
基本概念
-
它可以返回右表中所有行和左表中与之匹配的行(与左外相反)。
-
如果左表中没有匹配的数据,则填充 NULL 值。
-
-
示例(将左外中的例子以右外的方式实现)
-
查询任职部门名为 sal 和 it 的员工信息(应将部门信息全部保留)
select e.* from employees as e right join departments as d on d.department_id = e.department_id where d.department_name in ('sal', 'it');
-
查询所有员工的名字和所属部门的名称(应将员工名字全部保留)
select first_name, department_name from departments as d right join employees as e on e.department_id = d.department_id;
-
查询所有部门的名称以及该部门的平均工资 average_salary (不要小数部分),并按平均工资降序排序。(应将部门名称全部保留)
select department_name, truncate(avg(salary), 0) as average_salary from employees as e right join departments as d on d.department_id = e.department_id group by department_name order by average_salary desc;
-
3.全外连接
- 基本概念
- 返回两个表中所有行的组合,并将它们按照共同的列进行匹配。
- 在一个全外连接中,即使没有匹配的数据,也会保留两个表中的所有行。