首先,以下查询例子都以 t_orderitem 表为例。表数据如下。
DQL语句
DQL,数据查询语言(Data Query Language),查询不会对数据库中的数据进行修改,只是显示数据的方式。
select 语句的功能
- 从一个或多个表中检索一个或多个数据列
- select 的操作方式:投影操作、选择操作、连接操作
- 投影操作是对列的操作(用 select 列名实现读取某个单列)
- 选择操作是从表中摘取符合条件的数据的操作
- 连接操作是对 2 张表的操作,例如 连表查询等 ```plsql — 投影操作 select item_id from t_orderitem;
— 选择操作 select * from t_orderitem where item_id=1;
— 连表操作 select it.pname, it.price, it.num, o.cdate from t_order o join t_orderitem it on o.order_id = it.order_id;
<a name="MYGCe"></a>
## select语句的基本语法
1. 基本语法
```plsql
select *|{ [DISTINCT] column | expression [alias], ... }
from table;
- select 确定哪些列
- from 确定哪张表
- 语句组成部分
在最简单的 select 语句中必须包含以下内容
- 一个 select 子句,指定被显示的列
- 一个 from 子句,指定从哪张表查询数据
- select 子句后面跟哪些内容
- 通配符(*):查询表的所有列名
- distinct 字段名:去除该字段的重复值,并且 distinct 只能跟在 select 后面。例如查询两行数据的 num 都是 10,那么结果就只会有一个 10。
- column/expression:指定的字段名或表达式
- column alias:列名,指定该列名的别名或者表的别名
通配符*
-- 通配符,查询所有的列
select * from t_orderitem;
去除重复值distinct
-- distinct去除重复值,其后必须使用列名,不能使用计算表达式
select distinct num from t_orderitem;
select distinct 1+1 from dual; -- 正确
select distinct price*12 from t_orderitem; -- 错误
表达式expression
-- 表达式expression,dual是mysql中的虚表
select 1+1 from dual;
select 1+2; -- 等价于 select 1+2 from dual;
别名alias,可以给指定的列指定别名,也可以给指定的表指定别名
-- 给列指定别名alias,AS可以省略
select 1+1 'result' from dual;
select 1+1 as 'result' from dual;
select pname na, price pr, num numb from t_orderitem;
-- 给表指定别名
select it.pname, it.price, it.num, o.cdate from t_order o join t_orderitem it on o.order_id = it.order_id;
DQL常用关键字
在number类型上使用算术表达式(加减乘除)
-- 在number类型上使用算术表达式(加减乘除)
select pname, price, num, price*num total from t_orderitem;
字段(列)别名
别名,上面的已经介绍过,下面是双引号的使用。
-- 别名包含空格、特殊字符、或希望大小写敏感,则用双引号将其括起来
select pname "NAME", price "price(¥)", num "NO ", price*num "总价" from t_orderitem;
算术表达式中null值的处理
空值在输入数据时,表示该字段没有指定值,也没有缺省值;
空值不等于0,也不等于空格;
算术表达式包含空值将导致结果为空;
算术表达式中包含空值需要用空值转换函数 coalesce 处理;
在 mysql 中有专门的函数去处理,IFNULL(表达式参数, 备用值)
。
-- null值处理,如果价格为null,则采用备用值0
select pname, price, num, ifnull(price, 0)*num "总价" from t_orderitem to2;
字符串拼接、单引号用法
- 在 oracle 中使用 ||,mysql 只支持 concat 函数,不支持 ||;
- 使用单引号表示字符串;
-- 字符串拼接 -- oracle中: select price||'(价格)' from t_orderitem; select concat('price', concat('价格', '$')), price from t_orderitem to2;
where子句
- where 子句紧跟在 from 子句之后,子句后可以跟 条件表达式、列名表达式、比较运算符、文字值;
- where 子句对表里记录进行过滤;
- where 子句后不能紧跟列的别名,可以跟表的别名;
【注意】sql 的执行顺序是先执行 from,再执行 where,最后再执行 select。所以当执行 where 时只能知道表的别名,但还不知道列的别名,所以不能使用列的别名。
-- 查询item_id=1的数据
select pname, price, num from t_orderitem to1 where to1.item_id=1;
-- 查询price<5的数据
select pname, price, num from t_orderitem to2 where to2.price < 5; --正确
select pname, price pr, num from t_orderitem to2 where to2.pr < 5; --错误
【总结】
- where 子句优先于 select 子句执行;
- where 中不能使用 select 中列的别名;
字符类型在where子句中的用法
- where 后的字符值要用单引号括起来;
- 字符类型的大小写是敏感的;
- where 后加比较运算符的用法如下:比较条件运算符用于一个表达式和一个值或另一个表达式的比较;
select pname, price, num from t_orderitem where pname = '苹果';
between…and 与 not between…and(闭合区间)
查询价格在[2,7]区间的数据
select pname, price, num from t_orderitem where price between 2 and 7;
查询价格不在[2,7]区间的数据
select pname, price, num from t_orderitem where price not between 2 and 7;
in/or表示或的用法(集合中筛选)
表示 或 的可以使用 or 写法,不过 or 表达式写起来会冗余,现在更多使用的是 in 写法。
-- or写法
select pid, pname, price, num from t_orderitem where pid = 101 or pid=102 or pid=103 or pid=201;
-- in写法
select pid, pname, price, num from t_orderitem where pid in (101, 102, 103, 201);
like运算符
在字符串比较中,可用 like
和 通配符
进行查找。
通配符种类:%
表示 0 或者多个字符,_
表示任意一个字符。
为了测试这里添加多一些数据。
-- 查询以'苹果'结尾的数据
select * from t_orderitem where pname like '%苹果';
-- 查询第二个字符是'果'且后面没有多余字符的数据
select * from t_orderitem where pname like '_果';
-- 查询第二个字符是'果'的所有数据
select * from t_orderitem where pname like '_果%';
-- 查询名称中带有下划线'_'的数据
select * from t_orderitem where pname like '%\\_%' escape '\\';
select * from t_orderitem where regexp_like(pname, '_');
is null
判断一个字符是否为空使用 is null
。
null 不能用等于和不等于跟任何值比较,包括它自身,所以不能使用 =、<> 来测试一列是否为空。
-- 判断列数据是否为null
select * from t_orderitem where price is null;
运算符的否定形式
- 逻辑比较运算符:不等于的写法:
<>
、!=
、^=
。但要注意,<>
是 sql 的标准写法,兼容性更好,!=
、^=
都是 oracle 平台的特性,移植性较差,所以开发中,尽量使用<>
表示不等于。 not in
表示不在某个区间is not null
表示不为空select * from t_orderitem where pid <> 101 and price >= 20; select * from t_orderitem where pid != 101 and price >= 20; select * from t_orderitem where pid ^= 101 and price >= 20;
and用法
and 同时满足两个条件的结果。
select * from t_orderitem where pid <> 101 and price >= 20;
示例结果同上。
order by子句
order by 是 select 语句后最后一个子句,表示排序。排序方式有:asc(升序、默认)、desc(降序)。
-- 按照价格升序
select * from t_orderitem where pid <> 101 and price >= 20 order by price asc;
-- 价格降序
select * from t_orderitem where pid <> 101 and price >= 20 order by price desc;
-- 多个字段时,先按照num升序,num相同时按照price降序
select * from t_orderitem order by num asc, price desc;
DQL的执行顺序
select语句的处理过程:
- 客户端发送一条查询给服务器,服务器先会检查查询缓存,如果命中了缓存,则立即返回存储在缓存中的结果。否则进入下一阶段;
- 服务器端进行 SQL 解析、预处理,再由优化器生成对应的执行计划;
- mysql 根据优化器生成的执行计划,调用存储引擎的 API 来执行查询;
- 将结果返回给客户端。
mysql 执行 sql 的详细过程。
sql 语句执行顺序。
to be continue…