MySQL学习笔记(四)——分组函数,分组查询,链接查询

做者:就叫易易好了

日期:2020/11/18

1、分组函数

功能:用做统计使用,又称为聚合函数或统计函数mysql

分类:web

sum函数

avg函数

max函数

min函数

count函数

如下代码演示均基于myemployees数据库,可在MySQL学习笔记(一)中下载sql

#简单的使用案例

SELECT SUM(salary) FROM employees;

做用:求employees表中全部员工的薪水之和

SELECT avg(salary) FROM employees;

做用:求employees表中全部员工薪水的平均值

SELECT max(salary) FROM employees;

做用:求employees表中全部员工的薪水的最大值

SELECT min(salary) FROM employees;

做用:求employees表中全部员工的薪水的最小值

SELECT count(salary) FROM employees;

做用:求salary这个字段的非空值的个数

特色:数据库

sum,avg通常用于处理数据类型

max,min,count能够处理任何类型

sum,avg,max,min,count都忽略null值

#与distinct函数搭配使用

SELECT SUM(DISTINCT salary),SUM(salary) FROM employees;

返回值后者要比前者大不少,由于distinct是去重函数,去掉了表格里面不少重复的值

对于count函数的详细介绍

SELECT (*) FROM employees;svg

在统计的过程当中,该行只要用一个值不为null,就能统计上函数

此语句常常用来统计全部行数的个数,通常用这个语句统计总行数学习

2、分组查询

若是咱们要查询employees表格中各部门的平均工资该怎么办呢?这个时候就须要使用分组查询了。code

group by 语句

语法:xml

select 分组函数blog

from 表

where 筛选条件

group by 分组的列表

查询列表必须特殊,要求是分组函数和group by后出现的字段。

#案例:查询每一个工种的最高工资

SELECT MAX(salary),jio_id

FROM employees

GROUP BY job_id

#案例:查询每一个位置上的部门个数

SELECT COUNT(*),location_id

FROM departments

GROUP BY

location_id;

一、添加筛选条件

#案例1:查询邮件中包含a的字符的,每一个部门的平均工资

SELECT AVG(salary),department_id

FROM employees

WHERE

email like '%a%'

GROUP BY

department_id;

#案例2:查询有奖金的每一个领导手下员工的最高工资

SELECT

MAX(salary),manager_id

FROM

employees

WHERE

commission_pct IS NOT NULL

GROUP BY

manager_id;

二、添加复杂的筛选条件

#案例1:查询哪一个部门的员工个数>2

思路:

·先查询每一个部门的员工个数

SELECT COUNT(*),department_id

FROM employees

GROUP BY department_id;

·根据上面的结果,出啊讯那个部门的员工个数>2

这个时候就须要有一个函数来链接上面的语句了

此时咱们是用HAVING

也就是:

SELECT COUNT(*),department_id

FROM employees

GROUP BY department_id

HAVING COUNT(*)>2;

#案例2:查询每一个工种有奖金的员工最高工资>12000的工种编号和最高工资

思路:先查询每一个工种有奖金的员工最高工资和工种编号,

再查询最高工资大于12000的人

SELECT

MAX(salary),job_id

FROM

employees

GROUP BY

job_id;

HAVING

MAX(salary)>12000

#案例3:查询领导编号>102的每一个领导手下的最低工资>5000的领导编号是哪一个,以及最低工资

思路:查询领导编号>102的每一个领导手下的领导编号,再查询最低工资大于5000的人

SELECT

MIN(salary),manager_id

FROM

employees

WHERE

manager_id>102

GROUP BY

manager_id

HAVING

MIN(salary)>5000;

三、按表达式或函数分组

#案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些

思路:先查询每一个长度的员工个数,

SELECT

COUNT(*),

LENGTH(last_name)

FROM

employees

GROUP BY

LENGTH(last_name)

HAVING

COUNT(*)>5;

四、按多个字段进行分组

#案例:查询每一个部门每一个工种的员工的平均工资

SELECT

AVG(salary),department_id,job_id

FROM

employees

GROUP BY

department_id,job_id;

五、添加排序

#案例:查询每一个部门每一个工种的员工的平均工资,而且按平均工资的高低显示

SELECT

AVG(salary),department_id,job_id

FROM

employees

GROUP BY

department_id,job_id

ORDER BY

AVG(salary) DESC;

3、链接查询

也就是多表查询,当查询的数据来自于多个表的时候,就会用到链接查询

笛卡尔乘积现象:表A有m行,表B有n行,笛卡尔乘积的结果有m*n行

beauty表:

mysql 连续两次分组_ci

boys表:

mysql 连续两次分组_字段_02

若是执行如下语句:

SELECT name,boyname

FROM boys,bueaty;

获得的即是:

mysql 连续两次分组_字段_03

显然……(You Know)

出现这样的缘由是没有有效的链接条件,这个时候咱们须要添加有效的链接条件才能够避免这种尴尬的事情发生。

分类:

按年代分类

sq192标准:仅仅支持内链接

sq199标准:支持全部内链接+外链接(左外和右外)+交叉链接

按功能分类

内链接

等值链接

非等值链接

自链接

外链接

左外链接

右外链接

全外链接

交叉连结

一、sq192标准

1.1 等值链接

#案例1:查询女神名和对应的男神名

SELECT NAME,boyName

FROM boys,beauty

WHERE beauty.boyfriend_id=boys.id;

#案例2:查询员工名和对应的部门名

SELECT last_name,department_name

FROM employees,departments

WHERE employees.`department_id`=departments.`department_id`;

#案例3:为表取别名,提升语句简洁度,区分多个重名字段

查询员工名,工种号,工种名

SELECT last_name,e.job_id,job_title

FROM employees AS e,jobs

WHERE e.`job_id`=jobs.`job_id`;

注意:若是取了别名,查询的字段就不能使用原来的表名去限定

FROM语句中表格的顺序能够互换

#案例4:查询有奖金的员工名,部门名

SELECT last_name,department_name,commission_pct

FROM employees e,departments d

WHERE e.`department_id`=d.`department_id`

AND e.`commission_pct` IS NOT NULL;

#案例5:查询城市名中第二个字符为O的部门名和城市名

SELECT department_name,city

FROM departments d,locations l

WHERE d.`location_id`=l.`location_id`

AND city like '_o%';

加入分组

#案例6:查询每一个城市的部门个数

SELECT COUNT(*) 个数,city

FROM departments d,locations l

WHERE d.`location_id`=l.`location_id`

GROUP BY city;

加入排序

#案例7:查询每一个工种的工种名和员工个数,而且按员工个数降序排列

SELECT job_title,COUNT(*)

FROM employees e,jobs j

WHERE e.`job_id`=j.`job_id`

GROUP BY job_title

ORDER BY COUNT(*) DESC;

实现三表链接

#案例8:查询员工名,部门名和所在的城市

SELECT last_name,department_name,city

FROM employees e,departments d,locations l

WHERE e.`department_id`=d.`department_id`

AND d.`location_id`=l.`location_id`;

1.2 非等值链接

咱们先创建一个等级表:

CREATE TABLE job_grades

(grade_level VARCHAR(3),

lowest_sat INT,

highest_sal INT);

INSERT INTO job_grades

VALUES('A',1000,2999);

INSERT INTO job_grades

VALUES('B',3000,5999);

INSERT INTO job_grades

VALUES('C',6000,9999);

INSERT INTO job_grades

VALUES('D',10000,14999);

INSERT INTO job_grades

VALUES('E',15000,24999);

INSERT INTO job_grades

VALUES('F',25000,40000);

样式以下:

mysql 连续两次分组_外链_04

#案例:查询员工的工资和工资等级

SELECT salary,grade_level

FROM employees e,job_grades g

WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`;

二、sql99语法

语法:

SELECT 查询列表

from 表1 别名 【链接类型】

join 表2 别名

on 链接条件

where 筛选条件

group by 分组

having 筛选条件

order by 排序列表

(提升了可读性,实现了分离)

分类

内链接:inner

外链接

左外:left [outer]

右外:right[outer]

全外:full [outer]

交叉链接:cross

内链接

语法:

select 查询列表

from 表1 别名

inner join 表2 别名

on链接条件;

等值链接:

#案例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 e.`last_name` LIKE '%e%';

添加分组+筛选

#案例3:查询部门个数>3的城市名和部门个数

SELECT city,COUNT(*) 部门个数

FROM departments d

INNER JOIN locations l

ON d.`location_id`=l.`location_id`

GROUP BY city

HAVING count(*)>3;

添加分组+筛选+排序

#案例4:查询哪一个部门的员工个数>3的部门名和员工个数,并按个数降序

SELECT COUNT(*),department_name

FROM employees e

INNER JOIN departments d

ON e.`department_id`=d.`department_id`

GROUP BY department_name

HAVING COUNT(*)>3

ORDER BY COUNT(*) DESC;

多表链接

#案例:查询员工名、部门名、工种名、并部门名降序排列

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;

非等值链接

#案例1:查询员工的工资级别

SELECT salary,grade_level

FROM employees e

INNER JOIN job_grades g

ON salary between g.`lowest_sal` AND g.`highest_sal`;

#案例2:查询工资级别的个数>20的个数,而且按工资级别降序

SELECT COUNT(*),grade_level

FROM employees e

INNER JOIN job_grades g

ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`

GROUP BY grade_level

HAVING COUNT(*)>20

ORDER BY grade_level DESC;

自链接

#案例:查询员工的名字,上级的名字

SELECT e.last_name,m.last_name

FROM employees e

JOIN employees m

ON e.`manager_id`=m.`employee_id`;