所谓复杂查询其实就是子查询,因为查询中嵌套着查询(无限套娃),导致查询复杂度被无限放大。

排序

ORDER BY 子句用来设定按哪个字段哪种方式进行排序,再返回搜索结果

  1. ;默认 ASCA升序)DESC(降序)
  2. SELECT * FROM info ORDER BY balance [ASC];
  3. SELECT * FROM info ORDER BY balance DESC;

多字段排序

  1. SELECT * FROM info ORDER BY balance [ASC],ORDER BY age DESC;

分组

GROUP BY 语句根据一个或多个列对结果集进行分组
WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)

联查

UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中
UNION ALL:返回所有结果集,包含重复数据
UNION DISTINCT:删除结果集中重复的数据(默认)

连表

INNER JOIN(内连接或等值连接):获取两个表中字段匹配关系的记录
SQL 复杂查询 - 图1
LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录
SQL 复杂查询 - 图2
RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录
SQL 复杂查询 - 图3

实例

分组联查

需求:列出薪资高于部门号为 30 下的所有员工的姓名、薪资、部门名称

  1. SELECT e.ename , e.sal , d.dname
  2. FROM emp e JOIN dept d ON e.deptno = d.depno
  3. WHERE e.sal > ALL(SELECT sal FROM emp WHERE dempno = 30);

需求:列出公司各等级雇员的数量和平均工资

  1. SELECT s.grade , COUNT(e.empno) , AVG(e.sal)
  2. FROM emp e JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal
  3. GROUP BY s.grade;

需求:列出与张三(排除)从事相同工作的所有员工及部门名称,部门人数

  • 列出与张三(排除)从事相同工作的所有员工及部门名称

    1. SELECT e.* , d.dname
    2. FROM emp e JOIN dept d ON e.deptno = d.depno
    3. WHERE e.job = (SELECT job FROM emp WHERE ename = '张三')
    4. AND e.ename != '张三';
  • 统计部门人数

    1. SELECT deptno , COUNT(1) dc
    2. FROM emp
    3. GROUP BY deptno
  • 三表联查,完成

    1. SELECT e.* , d.dname
    2. FROM emp e JOIN dept d ON e.deptno = d.depno
    3. JOIN (SELECT deptno , COUNT(1) dc FROM emp GROUP BY deptno) n ON e.deptno = n.depno
    4. WHERE e.job = (SELECT job FROM emp WHERE ename = '张三')
    5. AND e.ename != '张三';