概述
本章,您将学习 MySQL 中有关 DQL 的知识。
在 MySQL 基础篇的整个知识架构中,DQL 的内容最多也最常使用,学习时应该重点掌握与训练。
DQL 主要包含以下内容:
- 条件查询
- 排序查询
- 函数
- 连接查询
- 嵌套查询
- 分页查询
- 联合查询
受限于篇幅,本篇文档只说明条件查询与排序查询。
基础 DQL
基础 DQL 的语法:
select 查询列表 from 表名;
查询列表可以是:
- 字段名
- 常量值
- 表达式
- 函数
示例使用如下:
-
单表单字段查询
Mysql > use world; Mysql > select name from city;
-
单表多字段
Mysql > use world; Mysql > select
name
,population from city;多个字段用
,
进行分割,全部字段可用*
进行表示。如你所见,有时为了避免和关键字冲突,可用反引号来包含字段名。 -
别名
我们可以使用
as
关键字对字段名称或表名称进行别名的定义,有时也用空格对表名或字段名进行别名的定义。我们建议最好使用反引号包含字段别名或表别名,这能避免语法歧义且最显眼。Mysql > use world; Mysql > select
name
as城市名称
,Population as人口数量
from city as城市表
; Mysql > selectname
城市名称
,Population as "人口数量" from city;不同的 RDBMS 对别名的处理有些细微差异,绝大多数都支持使用双引号进行包含,但在 MySQL 中则建议使用反引号包含。如下示例所示,这在 MySQL 8 中会提示语法错误:
Mysql > select * from city as "city-info";
-
去重
可使用
distinct
对查询的结果去重,需要注意的是,该关键字只能出现在select
的相关语法中且只能出现一次。Mysql > select distinct
CountryCode
, ID from city;在该示例中,去除的是这两列结果的重复项。
-
字段数据拼接
若两边都是数值型,使用
+
则会正确输出:# 输出结果 200 Mysql > select 100+100 as
temp
;若一边是数值型,一边是字符型,使用
+
拼接时会将字符型转换为数值 0 :# 此处的 like 是一个常数(MySQL 运行过程中不会改变的数据被称为常数),使用单引号或双引号包含是符合语法规则的。 ## 输出结果 100 Mysql > select "like"+100 as
tmp1
;只要有 null 存在,使用
+
进行拼接一定返回 null:Mysql > select null+null as name1; Mysql > select null+100 as name2; Mysql > select null+'jim' as name3;
上面的示例都是使用常量进行数据拼接,若要实现字段之间的拼接,则需要使用
concat()
函数,如下示例:Mysql > select concat(countrycode,"=",name) as
newname
from city; AFG=Kabul AFG=Qandahar AFG=Herat AFG=Mazar-e-Sharif NLD=Amsterdam NLD=Rotterdam NLD=Haag NLD=Utrecht NLD=Eindhoven NLD=Tilburg NLD=Groningen ...
条件查询
我们需要 where
关键字,语法如下:
select 查询列表 from 表名 where 筛选条件;
比如 select * from city where id="100";
这条 SQL 语句,其执行顺序为:
- 定位到库
- 定位到具体的表
- 根据筛选条件筛选出具体的一行一行数据
- 根据字段显示出相应的数据
筛选条件可以有 —— 条件表达式、逻辑表达式、模糊查询关键字
条件表达式
>
– 表示大于<
– 表示小于>=
– 表示大于等于<=
– 表示小于等于<>
– 表示不等于<=>
– 表示安全等于,不太常用=
– 表示等于
逻辑表达式
and
– 逻辑与。即都为 1 (真),返回结果才为 1 (真);有一个 0 (假),返回 0 (假)or
– 逻辑或。任意一个为 1 (真),返回结果为 1 (真);都为 0 (假),则返回结果 0 (假)not
– 逻辑非。取反,本身为 1 (真),返回结果 0 (假);本身为 0 (假),返回结果 1 (真)
模糊查询关键字
like
between and
in
not in
is null
is not null
条件查询示例
# 查询出人口数量大于一亿且属于亚洲的国家
Mysql > use world;
Mysql > select `name` as `国家名称` from country where Population>"100000000" and continent="Asia";
# 取反
Mysql > select `name` as `国家名称` from country where not (Population>"100000000" and continent="Asia");
# 有时在一条 SQL 语句中会同时出现 and 、or 和 not 关键字,为了区分层次关系,可以使用括号
# 人口小于1亿或不在亚洲的国家,从这些国家中筛选出 GNP 小于 100 的国家
## 下面这两条 SQL 语句是等同的
Mysql > select `name` from country where (Population<"100000000" or continent<>"Asia") and (GNP<100);
## 当你加了 not 关键字,不仅是条件表达式发生变化,连带的逻辑表达式也会发生变化
Mysql > select name from country where not ((Population>"100000000" and continent="Asia") or (GNP>="100"));
# 模糊查询,我们可以使用关键字 like
## 模糊查询中,"%" 表示通配符,"_" 表示单个字符。当遇到特殊符号时,使用 "\" 进行转义
Mysql > select * from country where name like "ch%";
# 根据数值的范围筛选数据,使用 between and 关键字。需要注意的是,有些 RDBMS 包含边界(即闭区间),有些不包含边界(即开区间),MySQL 8 中包含边界(闭区间)
Mysql > select * from city where id between 1 and 10;
## 等同于
Mysql > select * from city where id>=1 and id<=10;
# 使用 in 或 not in 关键字过滤范围
## 数值型
Mysql > select * from city where id in (1,2,3,4,5,6,7,8,9,10);
## 字符型
Mysql > select * from city where name not in ("kabul","qandahar");
# is null 和 is not null 关键字
# 查询平均寿命为 null 的国家
# 这两条 SQL 语句等同
Mysql > select name from country where LifeExpectancy is null;
Mysql > select name from country where LifeExpectancy<=>null;
# 简单的表嵌套
Mysql > select * from (select * from city where name not in ("kabul","qandahar")) as `newtable` where id in (1,10,15,100);
排序查询
- 升序(从小到大)- 使用到的关键字是
order by
,可省略关键字asc
- 降序(从大到小)- 使用到的关键字是
order by
,需要关键字desc
比如这样一条 SQL 语句:
Mysql > select * from country where `Continent`="Asia" and GNP>100000 order by `Population`,LifeExpectancy;
其执行顺序为:
- 定位到库
- 定位到具体的表
- 筛选出属于亚洲且GNP大于100000的国家数据
- 根据字段呈现出相应的数据
- 根据这些数据做排序操作,先按照人口数量(Population) 进行升序,若人口数量相同,则再按照人口的平均寿命(LifeExoectancy) 进行升序
升序或降序除还可以用于一些做了运算的表达式,例如:
# ifnull() 函数用来处理人口平均寿命的 null 值
Mysql > select * , ifnull(LifeExpectancy,0)*10 as 平均年龄 from country where IndepYear is not null order by 平均年龄;
也支持按照特定函数进行排序:
Mysql > select name,length(`name`) as `国家字符长度` from country order by length(`name`);
