分享

数据库高级搜索 聚合函数

 路人甲Java 2022-12-26 发布于北京

聚合函数

聚合函数在数据的查询分析中,应用十分广泛。聚合函数可以对数据求和、最大值和最小值、求平均值 等等。

# 求公司员工的平均月收入:
SELECT AVG(sal+IFNULL(comm,0)) AS avg FROM t_temp;
# sal和comm是列名。  AVG求平均值聚合函数。
# IFNULL(comm,0),如果comm的值为null,则赋值0

SUM函数

SUM函数用于求和,只能用于数字类型,字符类的统计结果为0,日期类型统计结果是毫秒数相加。

SELECT SUM(ename) FROM t_emp;
# ename 列名
SELECT SUM(sal) FROM t_emp WHERE deptno IN(10,20);
# sal,deptno列名 t_emp表
# deptno IN(10,20)  deptno的值在(10,20)里面就匹配

MAX函数

MAX函数用于获得非空值的最大值。

SELECT MAX(comm) FROM t_emp;

# 查询员工名字最长的是几个字符:
SELECT MAX(LENGTH(ename)) FROM t_emp;
# LENGTH() --统计字符个数

MIX函数

MIN函数用于获得非空值的最小值。

SELECT MIN(empno) FROM t_emp;

AVG函数

AVG函数用于获得非空值的平均值,非数字数据统计结果为0

COUNT函数

COUNT(*)用于获得包含空值的记录数,COUNT(列名)用于获得包含非空值的记录数。

SELECT COUNT(*) FROM t_emp;
# 查询所有的记录,包含空值

SELECT COUNT(comm) FROM t_emp;
# 查询佣金表数据,不统计空值

分组查询

为什么要分组?

默认情况下汇总函数是对全表范围内的数据做统计。

GROUP BY 子句的作用是通过一定规则将一个数据集划分成若干个小的区域,然后针对每个小区域分别进行数据汇总处理。

SELECT deptno,AVG(sal) FROM t_emp GROUP BY deptno;
# GROUP BY deptno;  deptno是员工部门,里面包含10,20,30部门,GROUP BY就把他们10,20,30分别分成一个组
# 然后deptno,AVG(sal) 显示部门编号和每个部门的平均薪水。
# ROUND(AVG(sal))  --》 把小数转换成整数。

逐级分组

  • 数据库支持多列分组条件,执行的时候逐级分组。
  • 查询每个部门里,每种职位的人员数量和平均底薪
SELECT deptno,job,COUNT(*),AVG(sal) FROM t_emp GROUP BY deptno,job ORDER BY deptno;
# GROUP BY deptno,job 先按照部门分组,再对职位进行分组
# ORDER BY deptno; 根据部门进行排序

对SELECT子句的要求

查询语句中如果含有GROUP BY子句,那么SELECT子句中的内容就必须要遵守规定:SELECT子句中可以包括聚合函数,或者GROUP BY子句的分组列,其余内容均不可以出现在SELECT子句中。

SELECT deptno,AVG(sal),SUM(sal),MAX(SAL),MIN(sal),COUNT(*) FROM t_emp GROUP BY deptno WITH ROLLUP;
# WITH ROLLUP 对汇总的结果再次汇总计算

GROUP_CONCAT函数

GROUP_CONCAT函数可以把分组查询中的某个字段拼接成一个字符串,返回一条记录。

# 查询每个部门内底薪超过2000元的人数和员工姓名
SELECT deptno,GROUP_CONCAT(ename),COUNT(*) FROM t_emp WHERE sal>=2000 GROUP BY deptno;

查询语句中,各种子句的执行顺序

FROM->WHERE->GROUP BY->SELECT->ORDER BY->LIMIT

HAVING子句

HAVING子句跟在GROUP BY 子句后面,用作条件判断,类似WHERE.但是WHERE不能够对聚合函数进行筛选,HAVING不能单独使用,必须跟在GROUP BY后面

SELECT deptno FROM t_emp GROUP BY deptno HAVING AVG(sal)>=2000;

# 查询每个部门中,1982年一会入职的员工超过2个人的部门编号
SELECT deptno FROM t_emp
WHERE hiredate>="1982-01-01"
GROUP BY deptno HAVING COUNT(*)>=2;
ORDER BY deptno ASC;

HAVING子句的特殊用法

按照数字1分组,MySQL会依据SELECT子句中的列进行分组,HAVING子句也可以正常使用。

SELECT deptno,COUNT(*) FROM t_emp GROUP BY 1;

SELECT deptno,COUNT(*) FROM t_emp GROUP BY 1 HAVING deptno IN (10,20);
# 如果过滤的数据量比较大,能够使用WHERE过滤的尽量先使用WHERE对数据进行过滤

表连接查询

从多张表中提取数据

从多张表中提取数据,必须制定关联的条件。如果不定义关联条件就会出现无条件连接,两张表的数据会交叉连接,产生笛卡尔积。

# 错误的例子
SELECT empno,ename,dname FROM t_emp JOIN t_dept;

# 规定了连接条件的表连接语句,就不会出现笛卡尔积
SELECT e.empno,e.ename,d.dname FROM t_emp e JOIN t_dept d ON e.deptno=d.deptno;
# ON子句是做筛选用的,作用与WHERE是相同的

表连接的分类

  • 表连接分为两种:内连接和外连接
  • 内连接是结果集中只保留符合连接条件的记录
  • 外连接是不管符不符合连接条件,记录都要保留在结果集中

内连接的简介

内连接 最常见的一种表连接,用于查询多张关系表符合连接条件的记录。

SECT ... FROM 表1
[INNER] JOIN 表2 ON 连接条件
[INNER] JOIN 表3 ON 连接条件;

# 语法二:
SELECT ... FROM 表1 JOIN 表2 WHERE 连接条件;

# 语法三:
SELECT ... FROM 表1,表2 WHERE 连接条件;

# 查询每个员工的工号、姓名、部门名称、底薪、职位、工资等级
SELECT e.empno,e.ename,d.deptno,e.sal,e.job,s.grade FROM t_emp e JOIN t_dept d ON e.deptno=d.deptno JOIN t_salgrade s ON e.sal BETWEEN s.losal AND s.hisal
# 内连接的数据表不一定必须有同名字段,只要字段之间符合逻辑关系就可以。


# 查询与SCOTT相同部门的员工都有谁
SELECT e2.ename FROM t_emp e1 JOIN t_emp e2 ON e1.deptno=e2.deptno WHERE e1.name="SCOTT" AND e2.ename!="SCOTT";
# 相同的数据表也可以做表连接


# 查询底薪超过公司平均底薪的员工信息
SELECT e.empno,e.ename,e.sal
FROM t_emp e JOIN
(SELECT AVG(sal) avg FROM t_emp) t
ON e.sal>=t.avg;
# SELECT的查询结果可以作为一个表连接


# 查询RESEARCH部门的人数、最高底薪、最低底薪、平均底薪、平均工龄
# FLOOR()--取整,去掉小数位
# CELL()--取整,有小数位就进1,不管小数位是多少
SELECT COUNT(*),MAX(e.sal),MIN(e.sal),AVG(e.sal),
FLOOR(AVG(DATEDIFF(NOW(),e.hiredate)/365)) FROM t_emp e JOIN t_dept d ON e.deptno=d.deplno WHERE d.name="RESEARCH";

表的外连接

为什么要使用外连接

外连接与内连接的区别

外连接与内连接的区别在于,除了符合条件的记录之外,结果集中还会保留不符合条件的记录。

SELECT e.empno,e.ename,d.dname
FROM 
t_emp e
LEFT JOIN t_dept d ON e.deptno=d.deptno;
# LEFT JOIN 左外连接关键字
# RIGHT JOIN 右外连接关键字

(查询语句) UNION (查询语句) # 

左连接和右连接

左外连接 就是保留左表所有的记录,与右表做连接。如果右表有符合条件的记录就与左边连接。如果右表没有符合条件的记录,就用NULL与左表连接。右连接也是如此。

子查询

子查询是一种查询中嵌套查询的语句

注意:不推荐在WHERE语句中使用子查询,应当用表内连接查询

子查询可以写在三个地方:WHERE子句、FROM子句、SELECT子句,但是最有FROM子句子查询是最可取的。

单行子查询和多行子查询

  • 单行子查询的结果集中只有一条记录,多行子查询结果集有多行记录
  • 多行子查询只能出现在WHERE子句和FROM子句中

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多