SQLite3数据查询、排序与联合(Union)

本文介绍SQLite3数据库的基本查询方法,包括select语句、distinct关键字、查询条件、数据排序、指定返回记录数量、子查询的应用等操作,并介绍了如何通过数据联合操作垂直合并数据。

准备数据

本文测试数据准备语句如下。

SQLite3
create table t3(f1 text unique not null,
f2 integer,
f3 integer,
f4 integer,
f5 text);

insert into t3(f1,f2,f3,f4,f5)
values('user01',60,70,80,'111.001'),
('user02',60,80,70,'111.001'),
('user03',70,90,90,'111.001'),
('user04',80,70,70,'111.002'),
('user05',70,60,60,'111.002'),
('user06',80,70,70,'222.001'),
('user07',90,80,60,'222.002'),
('user08',70,90,60,'333.001'),
('user09',50,60,60,'333.002'),
('user10',80,80,80,'333.002');

代码中创建了t3表,包括5个字段,其中,f1和f5为文本类型,f2、f3、f4为整数类型。表中共添加了10条记录,接下来的查询结果会以这些数据为例。

使用select语句查询数据

查询数据可以使用select语句,其最简单的格式如下:

SQLite3
select <字段> from <表>;

此语句可以返回<表>中的指定<字段>的所有数据,其中,<字段>是返回数据的字段列表,多个字段名使用英文逗号(,)分隔,返回所有自定义字段时可以使用星号(*),如果需要显示rowid字段,需要显式指定,如“select rowid,* from t3;”。此外,对表名、字段名等对象名称,如果包含了空格等特殊字段,可以使用双引号或方括号定义,如"t3"、"f1"、[t3]、[f1]。

不显示重复记录(所有字段数据都相同的记录)时,可以在select关键字后使用distinct关键字,如下面的代码可以获取f5字段的数据列表。

SQLite3
select distinct f5 from t3;

执行结果如下图所示。

使用distinct关键字

指定查询条件时使用where关键字,并可以使用and、or、not运算符组合查询条件;对于复杂的组合条件,可以使用圆括号进行组织。

下面的代码会查询f2、f3、f4都大于或等于80的记录。

SQLite3
select rowid,* from t3
where f2>=80 and f3>=80 and f4>=80;

查询结果如下图所示。

查询结果

下面的代码可以显示f5字段中以'111'为前缀的记录。

SQLite3
select rowid,* from t3
where f5 like '111%';

查询结果如下图所示。

查询结果

使用文本相等的条件时需要注意,默认情况下文本是按二进制代码比较,也就是说会区分字母大小写,如下面的代码不会返回f1为'user01'的记录。

SQLite3
select rowid,* from t3
where f1 = 'User01';

如果指定比较文本不区分字母大小写,可以在f1字段后使用collate nocase,如下面的代码。

SQLite3
select rowid,* from t3
where f1 collate nocase = 'User01';

查询结果如下图所示。

查询结果

对查询结果排序时使用order by子句,如下面的代码,可以按f2字段升序排列。

SQLite3
select rowid,* from t3 order by f2;

查询结果如下图所示。

查询结果

升序是默认的排序方式,与排序字段名后添加asc关键字的效果相同;需要降序排列时,可以在排序字段名后添加desc关键字,如下面的代码。

SQLite
select rowid,* from t3 order by f2 desc;

代码查询结果如下图所示。

查询结果

排序时,还可以使用逗号分隔指定更多的排序字段和排序方法,当第一排序字段数据相同时,会按第二排序字段数据排序,以此类推。如下面的代码,首先按f2字段数据降序排列,数据相同时再按f3字段数据降序排列。

SQLite3
select rowid,* from t3 order by f2 desc, f3 desc;

查询结果如下图所示。

查询结果

指定查询结果返回的记录数量时可以使用limit子句,其常用格式如下:

  • limit n,返回前n条记录。
  • limit m,n,跳过m条记录,返回n条记录。
  • limit n offset m,跳过m条记录,返回n条记录。

如下面的代码可以返回f2数值最高的3条记录(不考虑重复数据)。

SQLite3
select rowid,* from t3 order by f2 desc limit 3;

查询结果如下图所示。

查询结果

如果需要以第3条记录的f2字段数据为准,返回大于等于其值的记录,可以将第3条记录的f2字段数据为判断条件的数据,如下面的代码。

SQLite3
select rowid,* from t3
where f2>=(select f2 from t3 order by f2 desc limit 2,1);

查询结果如下图所示。

查询结果

在上述SQL语句中,括号中的select语句可以称为子查询,子查询中首先对t3表的f2字段降序排列,然后跳过2条记录,取第3条记录的f2字段值,子查询的结果应该是一个数值;然后,使用此数值作为新的查询条件的数据,即查询t3表中f2字段大于或等于此数值的记录。

实际应用中,子查询还可以是一个数据集,如下面的代码,可以在t3表中查询t1表f1字段存在数据的记录。

SQLite3
select rowid,* from t3
where f1 in (select f1 from t1);

子查询中会读取t1表f1字段的数据,然后作为查询t3表数据in条件的数据列表,查询结果如下图所示。

查询结果

查询结果保存到数据表

将查询结果保存到数据表有两种基本的情况,先来看将查询结果保存到新表的操作,如下面的代码。

SQLite3
create table t3a as
select * from t3 where f2>=80;

此代码会将t3表中f2字段大于或等于80的记录保存到t3a表中,数据如下图所示。

查询结果

将查询结果保存到已存在的表时可以使用insert into语句,如下面的代码。

SQLite3
insert into t3a(f1,f2,f3,f4,f5)
select f1,f2,f3,f4,f5 from t3 where f2<80;

请注意,表的字段和查询结果的字段一一对应才能正确地添加数据。本例,代码会将t3表中f2字段小于80的记录添加到t3a表,这样t3a表的数据就和t3表相同了,只是rowid字段数据会按添加记录的顺序自动生成,如下图所示。

查询结果

联合

联合(Union)操作是将两个或更多查询结果的数据进行垂直方向的合并,需要注意的是,两个查询结果中的字段顺序和含义应该是相同的,联合操作结果中的字段会使用第一个查询结果的字段名。两个查询结果的联合操作需要使用union关键字,如下面的代码,会将t3和t3a表的数据进行联合。

SQLite3
select f1,f2,f3,f4,f5 from t3
union
select f1,f2,f3,f4,f5 from t3a;

联合操作会自动过滤相同的数据(即数据相同的记录只显示一条),所以,此代码只会显示10条记录。需要显示联合的所有记录时可以使用在union关键字后添加all关键字,如下面的代码。

SQLite3
select f1,f2,f3,f4,f5 from t3
union all
select f1,f2,f3,f4,f5 from t3a;

查询结果如下图所示。

查询结果

接下来执行下面的代码,从t3a表中删除f1字段等于'user06'到'user10'的记录。

SQLite3
delete from t3a
where f1 in ('user06','user07','user08','user09','user10');

两个查询结果使用except关键字时,可以显示存在于前一结果中,但不存在于后一结果的记录,如下面的代码。

SQLite3
select f1,f2,f3,f4,f5 from t3
except
select f1,f2,f3,f4,f5 from t3a;

本例,t3表中有f1字段为'user01'到'user10'的10条记录,t3a表中有f1字段为'user01'到'user05'的5条记录,查询结果只显示t3表中f1字段等于'user06'到'user10'的记录,如下图所示。

查询结果

两个查询结果使用intersect关键字可以显示数据的交集,即在两个查询结果都存在的记录。如下面的代码。

SQLite3
select f1,f2,f3,f4,f5 from t3
intersect
select f1,f2,f3,f4,f5 from t3a;

执行代码会显示t3表和t3a表中都存在的记录,即f1字段从'user01'到'user05'的记录,查询结果如下图所示。

查询结果