当前位置:   article > 正文

mysql重点攻克:分组查询和连接查询(建议收藏逐一攻克)_分组查询和连接查询作用一样嘛

分组查询和连接查询作用一样嘛

前言:

一、分组查询

1、语法

2、特点

3、案例解析

二、连接查询

1、内连接

2、外连接

3、交叉连接

总结


前言:

     在学习mysql或者其它数据库语言的时候,吃透DQL查询部分,就已经掌握大半了。所以这里就单独的来吃透分组查询和连接查询,当然子查询作为最难的部分单独出来,可以收藏作为复习文章哦。

使用的数据库一览表(作为案例提供):

数据库名:`myemployees`

数据库各表及其字段:

  • 部门表:
  • 员工表: 
  • 工资等级表: 
  • 工作信息表: 
  • 地址表: 

一、分组查询

介绍:

     一看到分组查询,我就想到了分组函数(max,min,avg)。当然,我还想到了group by(难以忘记刚学sql的时候支支吾吾和别人解释了半天什么叫分组查询,group by的作用......实在尴尬)。之前我们介绍过mysql的常见函数,其中就有分组函数,我们分组函数查询的结果往往是所有行的,而我们使用group by就将它进行了分组。

     例如:我们使用count(*)计算出了全校的人数,如果要求每个年级的人数,那么我就需要group by 将年级作为分组条件来进行分组查询。那么让我们一起来看看吧~

 

1、语法

  1. select 分组函数,列(要求出现在group by的后面)
  2. from
  3. where 筛选条件】
  4. group by 分组的列表
  5. having 筛选条件】
  6. order by 字句】

     而我们常见的分组函数就有:sum求和、avg平均值、max最大值、min最小值、count计算个数,上面语法中需要注意的是筛选条件的位置什么时候放在having之后,我的口诀就是分组函数的查询结果做列表的话条件放在having之后,否则放在where之后。

 

2、特点

     分组查询中的筛选条件分为两类

分组前后数据源位置关键字
分组前筛选原始表group by字句的前面where
分组后的筛选分组后的结果集group by字句的后面having

 

3、案例解析

1)查询每个工种的最高工资

     从题目我们了解到需要最高工资salary,分组条件就是工种号,那么代码如下:

  1. SELECT MAX(salary),job_id
  2. FROM employees
  3. GROUP BY job_id;

 

2)查询每个位子的部门个数

     查部门个数用count(*),然后通过location_id分组

  1. SELECT COUNT(*),location_id
  2. FROM departments
  3. GROUP BY location_id;

 

3)查询有奖金的每个领导手下的最高工资

     首先用到max查最高工资,然后通过领导分组,之后在where后面添加有奖金的这个条件(因为没有用到分组函数结果,所以不再group by后面添加)。

  1. SELECT MAX(salary),manager_id
  2. FROM employees
  3. WHERE commission_pct IS NOT NULL
  4. GROUP BY manager_id;

 

4)查询每个部门每个工种的员工的平均工资

     这里一看就是两个分组条件:部门和工种,然后分组函数为avg。所以有

  1. SELECT AVG(salary),department_id,job_id
  2. FROM employees
  3. GROUP BY department_id,job_id;

 

5)查询每个部门每个工种的员工的平均工资(大于1500)

    那么大于1500的条件一定是放在having之后的:

  1. SELECT AVG(salary) a,department_id,job_id
  2. FROM employees
  3. GROUP BY department_id,job_id
  4. HAVING a>1500;

     如果我们将平均工资排个序,那么就用到了order by

 

6)查询每个部门每个工种的员工的平均工资(大于1500)并降序排序

  1. SELECT AVG(salary) a,department_id,job_id
  2. FROM employees
  3. GROUP BY department_id,job_id
  4. HAVING a>1500
  5. ORDER BY a DESC;

     group by后面不可以起别名哦......


二、连接查询

介绍:

     提起连接查询,你可能想到了笛卡尔积,而我想到的就是字面上的连接,脑海里也会浮现初次学习时的内连接,外连接,交叉连接......

我们的连接按照功能分类:

内连接:

  • 等值连接
  • 非等值连接
  • 自连接

外连接:

  • 左外连接
  • 右外连接
  • 全外连接

交叉连接

语法:

     在我们学习语法之前,我们需要知道连接查询标准分为sql92标准sql99标准(顾名思义就是1992年和1999年提出的标准),虽然两者都是很好理解的,但是建议使用sql99标准的语法,不仅仅是因为它的逻辑性,也是因为sql92仅仅支持内连接,而sql99支持内连接+外连接(左外和右外)+交叉连接。全外连接很少用到,但是oracle支持(虽然建议使用sql99,但是内连接查询案例时也会展示sql92语法)。

  1. sql92语法:
  2. select 查询列表
  3. from 表 别名
  4. where 筛选条件】
  5. group by 分组】
  6. having 筛选条件】
  7. order by 排序列表】
  1. sql99语法:
  2. select 查询列表
  3. from1 别名 【连接类型】
  4. join2 别名
  5. on 连接条件
  6. where 筛选条件】
  7. group by 分组】
  8. having 筛选条件】
  9. order by 排序列表】
  10. 其中连接类型有:
  11. 内连接:inner
  12. 外连接:
  13. 左外:leftouter
  14. 右外:rightouter
  15. 全外:fullouter
  16. 交叉连接:
  17. cross

     观察一下其实sql92和sql99语法区别不是很大,表达的也是一致的。

使用的数据库一览表(作为案例提供):

数据库名:girls

各数据表及其字段:

管理员表:

女神表:

男神表:

 

1、内连接

1)等值连接(其实就是找交集部分)

看图理解:

案例:

1.1)查询女神名和对应的男神名

     那么我们的连接条件肯定是id号,即女神表中的男友id和男神表中的男神id,连接在一起就可以了。

  1. sql92标准:
  2. SELECT be.name,bo.`boyName`
  3. FROM beauty be,boys bo
  4. WHERE be.`boyfriend_id`=bo.`id`;
  5. sql99标准:
  6. SELECT be.name,bo.`boyName`
  7. FROM beauty be
  8. INNER JOIN boys bo
  9. ON be.`boyfriend_id`=bo.`id`;

     这么一对比,的确没有什么区别对吧。

 

1.2)查询每个工种的工种名和员工的个数,并且按照员工个数降序

     我们通过工种名分组,查个数,然后连接条件就是job_id,之后order by降序即可。

  1. sql92标准:
  2. SELECT COUNT(*),j.job_title
  3. FROM jobs j,employees e
  4. WHERE j.job_id=e.job_id
  5. GROUP BY j.job_title
  6. ORDER BY COUNT(*) DESC;
  7. sql99标准
  8. SELECT COUNT(*),j.job_title
  9. FROM jobs j
  10. INNER JOIN employees e
  11. ON j.`job_id`=e.`job_id`
  12. GROUP BY j.job_title
  13. ORDER BY COUNT(*) DESC;

 

特点:

  • 多表等值连接的结果为多表的交集部分
  • n表连接,至少需要n-1个连接条件
  • 多表的顺序没有要求
  • 一般需要为表起别名(特别是很长的那种表名,起了之后就要用别名去限制)
  • 可以搭配排序、分组、筛选(以下均可)

 

2)非等值连接(其实和上面的等值连接区别就是连接条件不是==,而是><或者其它的)

2.1)查询员工的工资和工资级别

     所以一看就知道连接条件是between and。

  1. sql92标准:
  2. SELECT salary,grade_level
  3. FROM employees e,job_grades j
  4. WHERE e.`salary` BETWEEN j.`lowest_sal` AND j.`highest_sal`;
  5. sql99标准:
  6. SELECT salary,grade_level
  7. FROM employees e
  8. INNER JOIN job_grades j
  9. ON e.`salary` BETWEEN j.`lowest_sal` AND j.`highest_sal`;

 

3)自连接(一定要使用别名哦)

3.1)查询员工名和上级的名称

     因为他们都在一张表里面,所以我们使用自连接,也就是连接自己。

  1. sql92标准:
  2. SELECT e1.employee_id,e1.last_name 老板,e2.`employee_id`,e2.last_name 员工
  3. FROM employees e1,employees e2
  4. WHERE e1.`employee_id`=e2.`manager_id`;
  5. sql99标准:
  6. SELECT e1.employee_id,e1.last_name 老板,e2.`employee_id`,e2.last_name 员工
  7. FROM employees e1
  8. INNER JOIN employees e2
  9. ON e1.`employee_id`=e2.`manager_id`;

 

2、外连接

应用场景:用于查询一个表中有,另一个表没有的记录

特点:

  • 外连接的查询结果为主表中的所有记录

           如果从表中有和它匹配的,则显示匹配的值

           如果从表中没有和它匹配的,则显示null

           外连接查询结果=内连接结果+主表中有而从表中没有的记录

  • 左外连接,left join左边的是主表;右外连接,right join右边的是主表
  • 左外和右外交换两个表的顺序,可以实现同样的效果
  • 全外连接=内连接的结果+表1中有而表2没有的+表2有但表1没有的

1)左外连接

1.1)查询哪个部门没有员工

     我们将部门表作为主表,之后连接员工表即可。

  1. SELECT d.*,e.employee_id
  2. FROM departments d
  3. LEFT OUTER JOIN employees e
  4. ON d.`department_id`=e.`department_id`
  5. WHERE e.`department_id` IS NULL;

 

2)右外连接

2.1)查询哪个部门没有员工

     和上面一样,交换一下即可,同样的效果。

  1. SELECT d.*,e.department_id
  2. FROM employees e
  3. RIGHT OUTER JOIN departments d
  4. ON d.`department_id`=e.`department_id`
  5. WHERE e.`department_id` IS NULL;

 

3)全外连接

     mysql不支持这个,效果如图示所占面积,这里给出一个例子看看语法形式(如果学习Oracle可以去了解):

  1. SELECT b.*,bo.*
  2. FROM beauty b
  3. FULL OUTER JOIN boys bo
  4. ON b.boyfriend_id=bo.id;

 

3、交叉连接

    相当于笛卡尔乘积,给出一个代码的例子:

  1. SELECT b.*,bo.*
  2. FROM beauty b
  3. CROSS JOIN boys bo;

总结

     分组查询和连接查询用的都是挺多的,所以在了解语法之后,还是需要多做练习题,希望对大家有帮助。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/680184
推荐阅读
相关标签
  

闽ICP备14008679号