数据查询

本文会介绍使用select语句查询数据的基本方法,包括如何设置数据源,如何选择字段,如何过滤重复数据,如何设置查询条件,如何对数据排序,如何指定返回记录数量,如何使用exists函数判断查询结果是否包含记录等。

本文示例会使用一个简化的用户信息表,创建表和添加数据的代码如下,可复制到HeidiSQL中执行。

MySQL
use cdb_demo;
-- 创建用户表
create table user1(
recid bigint not null auto_increment primary key,
username varchar(30) not null unique,
fullname varchar(30),
sex int not null default 0,
region varchar(30),
grade int
)engine=innodb default charset=utf8mb4;

-- 添加用户数据
insert into user1(username,fullname,sex,region,grade)
values('user01','张三',1,'11.00',14),
('user02','王二',1,'11.01',10),
('user03','李四',2,'11.01',5),
('user04','刘一兵',0,'11.02',9),
('user05','张瑞',0,'11.02',4),
('user06','John',1,'22.00',11),
('user07','Tom',1,'22.01',8),
('user08','Jerry',1,'22.02',7),
('user09','Mary',2,'21.00',10),
('user10','Smith',1,'21.01',3);

请注意,以两个减号(--)开始的内容是注释,用于在代码中添加说明,不属于执行代码。在SQL代码中,以--或#开始到本行结束的内容为注释内容,称为行注释;此外,定义多行注释(块注释)时可以使用/*开始,以*/结束,在此之间的注释内容可以有一行或多行。

select语句查询数据最基本的应用格式如下:

MySQL
select <字段> from <数据源>

其中,select和from为关键字。<字段>指定查询返回的字段,多个字段使用英文逗号分隔,返回全部字段时使用星号(*)。<数据源>即数据查询源,可以是数据表、视图或其它查询结果等。注意,字段、表等对象名中包含特殊字符时可以使用一对反单引号(`)格式书写,如`username`。下面的代码可以返回user1表的所有数据。

MySQL
use cdb_demo;
select * from user1;

查询结果如下图所示。

查询user1表数据

过滤重复数据

如果查询结果中有完全相同的记录,则可以在select关键字后添加distinct关键字进行过滤,如下面的代码。

MySQL
use cdb_demo;
select distinct sex from user1;

user1表中的sex字段,默认值为0,记录数据中包含了0、1、2,如果没有修改数据,则本查询会显示0、1、2。查询结果如下图所示。

使用distinct关键字过滤相同数据

需要返回某一字段出现的数据列表时,可以通过distinct关键字查询此字段数据。请注意,distinct关键字过滤的是查询结果中所有字段数据都相同的记录,返回多个字段的数据时,所有字段数据都相同的记录只会保留一条。

查询条件

指定查询条件时使用where子句,下面是一些基本的查询条件类型:

  • 等于,使用=运算符。
  • 不等于,使用<>或!=运算符。
  • 大于,使用>运算符。
  • 大于等于,使用>=运算符。
  • 小于,使用<运算符。
  • 小于等于,使用<=运算符。
  • 为空和不为空。判断字段数据是否为空时使用is null条件,不为空时使用is not null条件。
  • 指定范围。如<字段> between <x> and <y>,条件会返回<x>到<y>之间的记录,并且包含这两个数据。指定不包含两值范围之间的数据时可以在between关键字前添加not关键字。
  • 指定值列表。如<字段> in (<值列表>),如sex in (0,1,2)就是指定sex字段的数据必须是0、1、2中的一个。指定不包含列表中的值时,可以在in关键字前添加not关键字。

先来看一些查询条件的基础应用。下面的代码会显示sex不等于0的记录。

MySQL
use cdb_demo;

select * from user1
where sex<>0;

查询结果如下图所示。

查询结果

下面的代码会查询grade在9到15之间的记录。

MySQL
use cdb_demo;

select * from user1
where grade between 9 and 15;

查询结果如下图所示。

查询结果

文件或日期时间类型的数据需要使用一对英文单引号定义,如下面的代码会查询region等于“11.01”的记录。

MySQL
use cdb_demo;

select * from user1
where region='11.01';

查询结果如下图所示。

查询结果

同时使用多个条件查询时,可以使用如下两个运算符组合:

  • 与运算,使用and运算符,需要两个条件同时成立。
  • 或运算,使用or运算符,两个条件中有一个条件成立即可。

下面的代码会查询sex为1,并且grade大于9的记录。

MySQL
use cdb_demo;

select * from user1
where sex=1 and grade>9;

查询结果如下图所示。

查询结果

下面的代码会查询sex为1,或者grade大于9的记录。

MySQL
use cdb_demo;

select * from user1
where sex=1 or grade>9;

查询结果如下图所示。

查询结果

此外,如果需要得到条件相反的结果,可以在条件整体前使用not运算符,如下面的代码可以查询sex等于1,或grade大于9以外的记录,即上一查询相反的结果。

MySQL
use cdb_demo;

select * from user1
where not (sex=1 or grade>9);

查询结果如下图所示。

查询结果

排序

默认情况下,查询结果会使用主键数据排序,需要对查询结果中指定字段数据排序时可以使用order by子句,如下面的代码会通过grade数据排序。

MySQL
use cdb_demo;

select * from user1
order by grade asc;

查询结果如下图所示。

查询结果

代码中,在grade字段后使用了asc关键字,其含义为升序排列。实际上,默认情况下就是使用升序排序,也就是说将asc关键字删除会得到相同的查询结果。需要降序排列时,可以在排序字段名后使用desc关键字,如下面的代码会grade字段数据降序排列。

MySQL
use cdb_demo;

select * from user1
order by grade desc;

查询结果如下图所示。

查询结果

查询时,如果某一字段数据相同,还可以指定更多的排序字段,如下面的代码,首先会按sex字段数据升序排列,然后按grade字段数据降序排列。

MySQL
use cdb_demo;

select * from user1
order by sex, grade desc;

查询结果如下图所示。

查询结果

指定返回记录数量

指定返回记录数量时可以使用limit子句,如limit n就是只返回查询结果的前n条记录,如下面的代码会返回sex等于1的前3条记录。

MySQL
use cdb_demo;

select * from user1
where sex=1
limit 3;

查询结果如下图所示。

查询结果

使用limit子句时,还可以设置跳过一些记录后再返回指定数量的记录,在数据分页浏览时比较常用。可以通过两种格式设置,如:

  • limit m,n
  • limit n offset m

这两种格式的含义相同,都是跳过m条记录后返回n条记录。如下面的代码,就是跳过3条记录后返回2条记录。

MySQL
use cdb_demo;

select * from user1
limit 3,2;

查询结果如下图所示。

查询结果

本例,使用“select * from user1 limit 2 offset 3;”语句会得到相同的查询结果。应用中,如果需要对查询结果分页返回,可以使用“limit (p-1)*n, n”公式计算,其中,p为第几页,n为每页多少行。

需要注意,使用limit指定返回记录数量时,如果查询结果记录少于指定的数值,则返回所有记录。

exists函数

有时候,可能并不需要读取查询的数据,只需要判断查询结果是否包含数据记录,此时可以使用exists函数,其格式为exists(<查询语句>),当<查询语句>结果包含数据时返回1,否则返回0。如下面的代码会判断sex是否有等于3的记录。

MySQL
use cdb_demo;

select exists(select sex from user1 where sex=3);

执行查询会显示0,即没有sex等于3的记录。可以修改查询条件来观察执行结果。

本文使用的user1表有10条记录,可以方便核对查询结果是否与查询条件匹配,可以在测试中修改代码并观察查询结果。更多数据查询和运算方法会在后续文章中介绍。