数据统计分析:
聚合函数:
聚合函数可以对数据求和,求最大值和最小值,求平均值等等。
1.AVG() 2.SUM()只能用于数字类型 3.MAX() 4.MIN() 5.AVG() 6.COUNT(*)用于获得包含空值的记录数
聚合函数不能出现在where语句里面,原因很简单,需要先执行where子句才能确定范围,才能执行聚合函数,ON可以与WHERE替换。
分组查询:
1.group by 子句(在where子句后面)
2.逐级分组:
SELECT deptno,job,COUNT(*),AVG(sal) FROM t_emp GROUP BY deptno,job ORDER BY deptno;(查询每个部门里每种职位的人员数量和平均底薪)
对select语句的要求:
查询语句中如果含有group by子句,那么select子句中的内容就必须要遵守规定:select子句中可以包括聚合函数,或者group by子句的分组列,其余内容均不可以出现在select子句中。
3.对分组结构再次做汇总计算:
group by with rollup;
4.group_councat函数:
group_concat函数可以把分组查询中的某个字段拼接成一个字符串。
SELECT deptno,COUNT(*),GROUP_CONCAT(ename) FROM t_emp WHERE sal>=2000 GROUP BY deptno;
5.round函数——>将小数位四舍五入取整
各种子句的执行顺序:from——>where——>group by——>select——>order by——>limit
HAVING 子句:(只能用在group by子句里面,不能完全替代where子句)
解决在where语句内出现聚合函数的情况。(例如:查询部门平均底薪超过2000元的部门编号)
SELECT deptno,ROUND(AVG(sal)) FROM t_emp GROUP BY deptno HAVING AVG(sal)>2000;
having子句里面不能出现字段(sal > avg(sal)),但可以出现具体数值(2000>avg(sal))必须要用表连接才行。
多表连接查询:从多张表中提起数据,必须指定关联条件,否则会产生笛卡尔积
内连接:
集中只保留符合连接条件的记录。
内连接的多种语法形式:
1 SELECT ...... FROM 表1 JOIN 表2 ON 连接条件; 2 SELECT ...... FROM 表1 JOIN 表2 WHERE 连接条件; 3 SELECT ...... FROM 表1,表2 WHERE 连接条件;
查询每个员工的工号,姓名,部门名称,底薪,职位,工资等级: 1 SELECT e.deptno,e.ename,d.dname,e.sal,e.job,s.grade 2 FROM t_emp e JOIN t_dept d ON e.deptno = d.deptno 3 JOIN t_salgrade s ON e.sal BETWEEN s.losal AND s.hisal 4 ORDER BY s.grade;
内连接的数据表不一定必须有同名字段,只要字段之间符合逻辑关系就可以。
查询与SCOTT相同部门的员工都有谁: SELECT ename FROM t_emp WHERE deptno = (SELECT deptno FROM t_emp WHERE ename = "SCOTT") AND ename != "SCOTT"; 这是子查询的方法,但是子查询会导致数据库查询效率降低
SELECT e1.ename FROM t_emp e1 JOIN t_emp e2 ON e1.deptno = e2.deptno WHERE e2.ename = "SCOTT" AND e1.ename != "SCOTT"; 使用内连接的方法,用相同表连接可以加快查询效率
一些题目:
查询底薪超过公司平均底薪的员工信息(选择查询出来的表也可以进行表连接)
内查询方法: SELECT ename FROM t_emp WHERE sal>(SELECT ROUND(AVG(sal)) from t_emp); 内连接方法: SELECT e.empno,e.ename,e.sal FROM t_emp e JOIN (SELECT ROUND(AVG(sal)) as avg FROM t_emp) t #新表格的连接 ON e.sal >= t.avg;
查询research部门的人数,最高底薪,最低底薪,平均底薪,平均工龄:
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.deptno WHERE d.dname="RESEARCH";
FLOOR函数(强制抹零)CEIL函数(强制进位)
查询每个底薪超过部门平均底薪的员工信息:
SELECT e.ename,e.deptno,e.sal,t.avg FROM t_emp e JOIN (SELECT deptno,AVG(sal) as avg FROM t_emp GROUP BY deptno) t ON e.deptno=t.deptno AND e.sal>t.avg;
外连接:
不管符不符合连接条件,记录都要保留在结果中。比如有的临时工没有部门,但是这条信息也要显示出来。
left join:左连接(保留左边的字段右边为null进行连接) right join:右链接(保留右边的字段左边为null进行连接)
查询每个部门的名词和部门里面的人数,如果没有部门的员工,部门名称用null代替:
使用union关键字将多个语句的查询结果进行合并
(SELECT d.dname,COUNT(e.deptno) FROM t_dept d LEFT JOIN t_emp e ON d.deptno=e.deptno GROUP BY d.deptno ) UNION (SELECT d.dname,COUNT(*) FROM t_dept d RIGHT JOIN t_emp e ON d.deptno=e.deptno GROUP BY d.deptno);
※查询每名员工的编号,姓名,部门,月薪,工资等级,工龄,上司编号,上司姓名,上司部门:
SELECT e.ename,e.empno,d.dname,e.sal+IFNULL(e.comm,0),s.grade, FLOOR(DATEDIFF(NOW(),hiredate)/365), t.dname AS mdname,t.empno AS mempno,t.ename AS mename FROM t_emp e LEFT JOIN t_dept d ON e.deptno = d.deptno LEFT JOIN t_salgrade s ON e.sal BETWEEN s.losal AND s.hisal LEFT JOIN ( SELECT e1.empno,e1.ename,d1.dname FROM t_emp e1 JOIN t_dept d1 ON e1.deptno = d1.deptno ) t ON e.mgr = t.empno
外连接注意事项:
内连接只保留符合条件的记录,所以查询条件写在on子句和where子句中的效果是相同的。但是外连接里,条件写在where子句里,不符合条件的记录是会被过滤掉的,而不是保留下来。
子查询:
单行子查询:
多行子查询:
查询同事:
SELECT ename FROM t_emp WHERE deptno IN (SELECT deptno FROM t_emp WHERE ename IN("FORD","MARTIN")) AND ename NOT IN ("FORD","MARTIN");
where子句中的多行子查询中,可以使用关键字IN,ALL,ANY,EXISTS(效率低)关键字来处理多行表达式结果集的条件判断。
where子查询:
执行效率最低,避免使用,换成表连接
from子查询:
查询效率最高
select子查询:
查询效率低下