高级查询 — 连接查询

关于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.全外连接
  • 基本概念
    • 返回两个表中所有行的组合,并将它们按照共同的列进行匹配。
    • 在一个全外连接中,即使没有匹配的数据,也会保留两个表中的所有行。

猜你喜欢

转载自blog.csdn.net/m0_60610120/article/details/131134869