本文会介绍使用select语句查询数据的基本方法,包括如何设置数据源,如何选择字段,如何过滤重复数据,如何设置查询条件,如何对数据排序,如何指定返回记录数量,如何使用exists函数判断查询结果是否包含记录等。
本文示例会使用一个简化的用户信息表,创建表和添加数据的代码如下,可复制到HeidiSQL中执行。
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语句查询数据最基本的应用格式如下:
select <字段> from <数据源>
其中,select和from为关键字。<字段>指定查询返回的字段,多个字段使用英文逗号分隔,返回全部字段时使用星号(*)。<数据源>即数据查询源,可以是数据表、视图或其它查询结果等。注意,字段、表等对象名中包含特殊字符时可以使用一对反单引号(`)格式书写,如`username`。下面的代码可以返回user1表的所有数据。
use cdb_demo; select * from user1;
查询结果如下图所示。
如果查询结果中有完全相同的记录,则可以在select关键字后添加distinct关键字进行过滤,如下面的代码。
use cdb_demo; select distinct sex from user1;
user1表中的sex字段,默认值为0,记录数据中包含了0、1、2,如果没有修改数据,则本查询会显示0、1、2。查询结果如下图所示。
需要返回某一字段出现的数据列表时,可以通过distinct关键字查询此字段数据。请注意,distinct关键字过滤的是查询结果中所有字段数据都相同的记录,返回多个字段的数据时,所有字段数据都相同的记录只会保留一条。
指定查询条件时使用where子句,下面是一些基本的查询条件类型:
先来看一些查询条件的基础应用。下面的代码会显示sex不等于0的记录。
use cdb_demo; select * from user1 where sex<>0;
下面的代码会查询grade在9到15之间的记录。
use cdb_demo; select * from user1 where grade between 9 and 15;
文件或日期时间类型的数据需要使用一对英文单引号定义,如下面的代码会查询region等于“11.01”的记录。
use cdb_demo; select * from user1 where region='11.01';
同时使用多个条件查询时,可以使用如下两个运算符组合:
下面的代码会查询sex为1,并且grade大于9的记录。
use cdb_demo; select * from user1 where sex=1 and grade>9;
下面的代码会查询sex为1,或者grade大于9的记录。
use cdb_demo; select * from user1 where sex=1 or grade>9;
此外,如果需要得到条件相反的结果,可以在条件整体前使用not运算符,如下面的代码可以查询sex等于1,或grade大于9以外的记录,即上一查询相反的结果。
use cdb_demo; select * from user1 where not (sex=1 or grade>9);
默认情况下,查询结果会使用主键数据排序,需要对查询结果中指定字段数据排序时可以使用order by子句,如下面的代码会通过grade数据排序。
use cdb_demo; select * from user1 order by grade asc;
代码中,在grade字段后使用了asc关键字,其含义为升序排列。实际上,默认情况下就是使用升序排序,也就是说将asc关键字删除会得到相同的查询结果。需要降序排列时,可以在排序字段名后使用desc关键字,如下面的代码会grade字段数据降序排列。
use cdb_demo; select * from user1 order by grade desc;
查询时,如果某一字段数据相同,还可以指定更多的排序字段,如下面的代码,首先会按sex字段数据升序排列,然后按grade字段数据降序排列。
use cdb_demo; select * from user1 order by sex, grade desc;
指定返回记录数量时可以使用limit子句,如limit n就是只返回查询结果的前n条记录,如下面的代码会返回sex等于1的前3条记录。
use cdb_demo; select * from user1 where sex=1 limit 3;
使用limit子句时,还可以设置跳过一些记录后再返回指定数量的记录,在数据分页浏览时比较常用。可以通过两种格式设置,如:
这两种格式的含义相同,都是跳过m条记录后返回n条记录。如下面的代码,就是跳过3条记录后返回2条记录。
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(<查询语句>),当<查询语句>结果包含数据时返回1,否则返回0。如下面的代码会判断sex是否有等于3的记录。
use cdb_demo; select exists(select sex from user1 where sex=3);
执行查询会显示0,即没有sex等于3的记录。可以修改查询条件来观察执行结果。
本文使用的user1表有10条记录,可以方便核对查询结果是否与查询条件匹配,可以在测试中修改代码并观察查询结果。更多数据查询和运算方法会在后续文章中介绍。