查询一个字段
select 字段名 from 表名;
查询多个字段
select 字段名1,字段名2,... from 表名;
查询多个字段
select * from 表名; # 此方式的缺点:效率低,可读性差 # 在开发中不建议使用,自己需要查询一下可以使用
给查询的列起别名
select 字段名1,字段名2 as 字段2别名 from 表名; # as 关键字可以省略 select 字段名1,字段名2 字段2别名 from 表名;
查询字段1、字段2,并给字段2以别名的形式呈现出来。
注意:原表字段名并不改变,select语句永远不会执行修改操作,只负责查询。
注意:在所有的数据库中,字符串统一使用单引号括起来,双引号在oracle数据库中用不了。但在MySQL中可以使用。
注意:字段名可以使用数学表达式直接进行操作
条件查询:查询表中符合一定条件的数据。
语法格式:
select 字段1,字段2,... from 表名 where 条件;
使用between...and...时,必须遵循左小右大的原则
判断是否为空不能用 = null;需要使用is null,因为数据库中的null不是一个值,不能用等号。
and的优先级高于or
% :表示任意多个字符
_ :表示任意一个字符
\ :转义字符
查询指定内容,并按照某个字段n排序(默认是升序,同asc(ascend))
select 字段1,字段2,... from 表名 order by 字段n;
查询指定内容,并指定按照某个字段n降序排列(descend:下降)
select 字段1,字段2,... from 表名 order by 字段n desc;
查询指定内容,并按照字段n降序,当n相同时按字段x升序排列
select 字段1,字段2,... from 表名 order by 字段n desc,字段x asc;
from > where > select > order by(排序总是在最后)
数据处理函数又称为单行处理函数。
单行处理函数的特点:一个输入对应一个输出。
多行处理函数的特点:多个输入对应一个输出。
lower | 转换小写 |
upper | 转换大写 |
substr | 取子串 |
length | 取长度 |
trim | 去空格 |
str_to_date | 将字符串转成日期 |
date_format | 格式化日期 |
format | 设置千分位 |
round | 四舍五入 |
rand | 生成0-1之间的随机数 |
ifnull | 可以将null转换成一个具体值 |
case..when..then..when..then..else..end | 有点像swith()语句 |
substr(被截取的字符串,起始下标,截取的长度)
注意:数据库中下标都是从1开始的。(没有0)
select后面不仅可以跟字段名,也可用直接跟字面值,用于打印该字面值。
round(值n,小数点后保留的位数)
round(f,0):把浮点数四舍五入取整。
在数据库中,只要又NULL参与的数学运算,计算结果都是NULL
ifnull(数据n,被当作哪个值); 如果数据n为NULL,则当作某个值处理。
分组函数又称为多行处理函数。
多行处理函数特点:多个输入对应一个输出
count | 计数 |
sum | 求和 |
avg | 求平均 |
max | 最大值 |
min | 最小值 |
注意:分组函数在使用的时候必须先进行分组,然后才能使用。如果没有分组,则默认整张表为一组。
分组函数会自动忽略NULL。
分组函数中count(*)和count(字段)的区别
count(字段):统计该字段下部位NULL元素的总数
count(*):统计表中的总行数
分组函数不能直接使用在where子句中。
错误示例:select name,sal from table where sal > min(sal);
分组函数可以组合起来一起使用
select sum(sal),min(sal),max(sal),avg(sal) from 表名;
分组查询:先对数据进行分组,再对每一组的数据进行操作。
分组查询涉及到两个子句:group by 和 having
group by:按照字段1进行分组,然后对每组的字段2进行求平均
select 字段1,avg(字段2) from 表名 group by 字段1;
group by实现双重分组,现根据字段1进行分组,在分好的组中再以字段2进行分组
select 字段1,字段2,avg(字段n) from 表名 group by 字段1,字段2;
注意:
在一条select语句中,如果有group by语句的话,select后面只能跟:参加分组的字段、分组函数。(其他的字段没有意义)
having:可以对分完组的数据进一步过滤
having不能单独使用,必须和group by联合使用
having不能代替where
优化策略
注意:where和having都能够进行的筛选操作,优先选择where。效率更高。
一个完整的select语句格式如下:(注:顺序不能颠倒)
select #查询,找出特定列 ... from #指明表名 表名 where #条件查询,找出特定行 ... group by #分组 ... having #过滤分组后的数据,不可单独出现 ... order by #排序 ...;
执行顺序
from > where > group by >having > select > order by
即先拿表 > 根据条件筛选符合要求的数据行 > 然后分组 > 再次对分组筛选 > 然后按要求拿行中的数据 > 最后排序输出
分组函数不能直接使用再where后面的原因?
如:select name from table where sal > min(sal);
答:因为where语句先group by执行,执行where语句时还没有进行分组,然而分组函数必须先分组然后才能执行,故分组函数不能直接使用再where后面。
分组函数可以直接使用再select后面的原因?
如: select min(sal) from table;
答:因为此时已经执行过group by语句了(即使没有定义group by也会默认把整张表分为一组),故可以执行分组函数。
去除指定字段的重复记录
select distinct 字段 from 表名;
联合多个字段去除重复的记录
select distinct 字段1,字段2,... from 表名;
错误写法:select 字段1,distinct 字段2 from 表名
连接查询:又称为多表查询。多个表联合起来跨表查询。
根据语法的年代分类
SQL92
SQL99
主要学习SQL99
根据表连接的方式分类
内连接
等值连接
非等值连接
自连接
外连接
左外连接(左连接)
右外连接(右连接)
全连接(了解)
当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数是两张表行数的乘积。
如果避免笛卡尔积现象?
在两张表进行连接的时候加条件进行限制。
常用操作:
select e.ename,d.dname -- 指明哪个字段是哪张表的 from emp e,dept d -- 表起别名 where e.deptno = d.deptno; -- SQL92语法
上述操作对表起了别名,并对指明哪个字段是哪张表的,可提高效率,非常重要
此时只是查询结果避免了笛卡尔积现象,查询的次数并没有减少。
故表的连接次数越多,效率越低。开发中应尽量避免表的连接
等值连接:表连接条件是等量关系。
select e.ename,d.dname from emp e inner join dept d on e.deptno = d.deptno; # 表连接条件是等量关系
SQL92和SQL99语法对比
select 表别名1.字段名1,表别名2.字段名2 -- 指明哪个字段是哪张表的 from 表名1 表别名1,表名2 表别名2 -- 表起别名 where (表连接条件) and (其他筛选条件); -- SQL92语法
SQL92的缺点:结构不清晰,表的连接条件和后期进一步的筛选条件,都放到了where后面
select 表别名1.字段名1,表别名2.字段名2 from 表名1 表别名1 inner join -- inner join 内连接 inner关键字可以省略 表名2 表别名2 on 表连接条件; where 其他筛选条件; -- SQL99语法
SQL99优点:表连接的条件是独立出来的,结构清晰。
非等值连接:表连接条件不是等量关系。
select e.ename,e.sal,s.grade from emp e inner join salgrade s on e.sal between s.losal and s.hisal -- 表连接条件不是等量关系 order by s.grade desc,e.ename asc;
自连接:同一张表中的不同字段需要进行连接。
select e1.empno,e1.ename,e1.mgr,e2.ename from emp e1 inner join emp e2 -- 把一张表看成两张表,起不同的别名 on e1.mgr = e2.empno order by e1.empno;
技巧:把一张表看成两张表,起两个不同的别名,语法格式不变
外连接的特点:通过right和left关键字,指定一张主表,查询时会把主表内容全部查询出来,如果副表中有满足表连接条件的数据也一并查询出来,没有的话显示为null。
而内连接:两张表没有主次关系。只有完全满足表连接条件的才会查询出来。
select e.ename,d.dname from dept d left outer join -- 左外连接,outer可省略 emp e on e.deptno = d.deptno;
select e.ename,d.dname from emp e right outer join -- 右外连接,outer可省略 dept d on e.deptno = d.deptno;
左连接和右连接两种写法可以相互转换。
外连接的查询结果条数一定 >= 内连接查询结果条数
select ... from a join b on a和b的连接条件 join c on a和c的连接条件 right join d on a和d的连接条件;
在一个select语句中,内连接和外连接可以混合使用。
子查询:select语句中嵌套select语句,被嵌套的select语句称为子查询。
子查询可以出现的位置:
select ..(select). from ..(select). where ..(select).
select ... from ... where ... > (select min(sal) from ...);
可以间接实现在where中使用分组函数
from后面加子查询,相当于把子查询的查询结果当作一张临时表
select ... from (子查询) where ...;
注意:select子句中的子查询一次只能返回一个查询结果,否则报错。
select e.ename,e.deptno,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;
union:可以用于合并两条select语句的查询结果
select ... from ... union select ... from ...;
使用条件:要求两条select语句查询结果的 列数相同 且 数据类型相同。
limit:用于提取查询结果中的某一部分数据。
用途:通常使用在分页查询中。提高用户体验。
格式:(使用在select语句的最后面)
完整格式:limit startIndex, length
startindex是起始下标(从0开始),length是长度
缺省用法:limit length
取前length个长度的数据。
select ename,sal from emp order by sal desc limit 0,5;
mysql中limit是在order by之后执行的。
每页显示pageSize条记录,
则第pageNo页:
limit (pageNo-1)*pageSize,pageSize
语法格式
select ... from ... where ... group by ... having ... order by ... limit ...;
执行顺序
from > where > group by > having > select > order by > limit