我们知道,增删查改这几种操作在开发过程中不可或缺,下面重点介绍的是查询操作
在数据库中,80%的操作是通过查询完成的.在实际开发中能中,不可能只会用到一张表,多表查询在查询中起很大作用.
多表联查
多表联查前提是需要把表都连接起来,一般分为内连接和外连接
内连接
就是A表内连接B表, A表中的记录与B表有对应的,才会查询出来,如果没有对应,这些表中的数据都不会出现
语法:SELECT * FROM 表名1 INNER JOIN 表名2 ON 连接条件;
外连接
分为左外连接和右外连接,其中外连接出来的数据可能存在有不满足条件的数据
左外连接:A left [outer] join B 左边的表数据全部出来,右边,没有连接的以null填上
右外连接:A right [outer] join B join右边的表的数据全部显示,左边没有得连接的以null填上
自连接
就是自己连接自己,也就是把一张表连接查询多次
在自连接查询中,必须要为表起别名,要不然我们不清楚所指定的条件、返回的字段,到底是哪一张表的字段。
语法:SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ... ;
子查询
子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。
语法:SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 );
实例
比如有一个员工表,有员工编号,名字,职业,mgr表示上一级管理者的员工编号,入职日期,薪水,提成,部门编号
还有另一张部门表,有部门编号,部门名,工作地址
1.列出至少有一个员工的所有部门名
SELECT d.dname,COUNT(1)人数 FROM dept d JOIN emp e ON d.deptno = e.deptno GROUP BY e.deptno HAVING COUNT(1) > 0;
这里使用了内连接,把两张表通过部门编号连接起来,根据部门编号进行分组,使用聚合函数count()来统计人数.
这里使用聚合函数count(1),它的底层原理是,由于NULL值是不参与所有聚合函数运算的,在表里多加一列常数,统计表里的常数1就可以统计出所有的人数.
2.列出薪水比‘SMITH’多的所有员工
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename = 'SMITH');
这里使用子查询,内嵌select,先执行括号里面的select语句.
3.列出所有员工的姓名以及他的经理的姓名
SELECT e.ename 员工,m.ename 经理 FROM emp e JOIN emp m ON e.deptno = m.deptno WHERE e.mgr = m.empno;
代码里面"e.ename 员工"是给ename起别名,为了让输出的表格看起来一目了然,起表名的语法:SELECT 字段1 [ AS 别名1 ] , 字段2 [ AS 别名2 ] ... FROM 表名;其中AS可以省略.
4.列出各种工作的最低薪水,显示最低薪水大于1500的记录
SELECT job,MIN(sal) FROM emp GROUP BY job HAVING MIN(sal) > 1500;
使用分组函数,如果后面要接条件语句的话,要使用having关键字,而不能使用where
5.查询EMP表中,工资第5位到第10位的员工信息
SELECT * FROM emp ORDER BY sal DESC LIMIT 5,5;
这里使用到limit关键字,LIMIT后面接起始索引, 查询记录数,注意的是,起始索引从0开始,起始索引 = (查询页码 - 1)* 每页显示记录数
6.列出入职日期早于他经理的所有员工的姓名
SELECT e.ename FROM emp e JOIN emp m ON e.deptno = m.deptno WHERE e.hiredate > m.hiredate;
这里使用的是自连接,用的是同一张表,值得注意的是,这时候必须要给表起别名,不然不知道指的是哪个数据
总结及注意
1.NULL值是不参与所有聚合函数运算的,在进行运算时,用IFNULL(),用0来替换那一列有NULL的值
2.在使用count()统计时,由于对NULL的忽略,可以借助count(常数列),底层意思是在表里多加1列常数1,然后统计表里的常数1的个数
3.where与having后面都接条件,但是它们是有区别的:1.having是对分组后的筛选,where对整张表的筛选;2.where不能对聚合函数进行判断而having可以
4.在自连接查询中,必须要为表起别名,要不然我们不清楚所指定的条件、返回的字段,到底是哪一张表的字段。
5.在子查询中,比较运算符只能与单个值比较,如果多个值比较,= 变为in;!=使用 not in;<或者>,结合any或者all使用
6.编写查询语句的顺序
SELECT selection_list /*要查询的列名称*/
FROM table_list /*要查询的表名称*/
WHERE condition /*行条件*/
GROUP BY grouping_columns /*对结果分组*/
HAVING condition /*分组后的行条件*/
ORDER BY sorting_columns /*对结果分组*/
LIMIT offset_start, row_count /*结果限定*/
数据库语句查询顺序