MySQL数据库-高级查询

数据统计分析:

  聚合函数:

    聚合函数可以对数据求和,求最大值和最小值,求平均值等等。

    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
) UNIONSELECT 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子查询:

    查询效率低下

MySQL数据库-高级查询

上一篇:JDBC第一部分


下一篇:SQL优化的一些方法