SQLite学习笔记(三)

概述

本篇文章将介绍 SQLite 中的函数,了解如何利用内置的函数来处理数据。文章结构如下:

  • 聚合函数介绍
  • 其他内置函数介绍
  • 时间和日期函数介绍
  • 数据类型的比较和NULL值的处理

一、聚合函数

SQLite 常用的聚合函数如下表所示,对于所有的聚合函数来说,关键字 DISTINCT 可以作为它们函数参数字段的前置属性,用以过滤重复的字段值:

函数名描述
count(x | *)计算字段x中非NULL行数,count(*)返回在同一组内的数据行数
avg(x)计算字段x的平均值
max(x)选择字段x的最大值
min(x)选择字段x的最小值
sum(x)为一个数值列计算总和
total(x)该函数不属于标准SQL,其功能和sum基本相同,但计算结果比sum更合理。比如当所有字段值均为NULL时,该函数返回0.0。再有就是该函数始终返回浮点型数值。该函数始终都不会抛出异常。
group_concat(x [,y])该函数返回一个字符串,该字符串将会连接所有非NULL的x值。该函数的y参数将作为每个x值之间的分隔符,如果在调用时忽略该参数,在连接时将使用缺省分隔符","

这里需要特别注意一下 count 函数,例如有表 Contacts 的数据如下所示:

sqlite> SELECT * FROM Contacts;
id          name        phone
----------  ----------  ----------
1           Marck       NULL
2           Beryl       10086
3           Micheal     10010
4           Tom         NULL

可以看到表中一共有4条数据,其中有两条的phone字段为空。当我们使用 count(*) 时,返回的是表的行数:

sqlite> SELECT count(*) FROM Contacts;
count(*)
----------
4

需要注意的是,即使某一行的数据全为 NULL(表格允许的话),那么 count(*) 依然会算上这一行数据。

而当 count 函数的参数为表格的某一字段时,返回的是该字段的非 NULL 行数:

sqlite> SELECT count(phone) FROM Contacts;
count(phone)
----------
2

二、其它函数

除了上述的聚合函数之外,SQLite 还提供了下列函数:

函数名描述
abs(x)返回参数x的绝对值
length(x)如果参数X为字符串,则返回字符的数量,如果为数值,则返回该参数的字符串表示形式的长度,如果为NULL,则返回NULL
upper(x)返回参数x的大写形式,该函数只能应用于ASCII字符
lower(x)返回参数x的小写形式,该函数只能应用于ASCII字符
random()返回一个介于 -9223372036854775808 和 +9223372036854775807 之间的伪随机整数
ltrim(x [,y])如果没有可选参数Y,该函数将移除参数X左侧的所有空格符;如果有参数Y,则移除X左侧的任意在Y中出现的字符。最后返回移除后的字符串
rtrim(x [,y])如果没有可选参数Y,该函数将移除参数X右侧的所有空格符;如果有参数Y,则移除X右侧的任意在Y中出现的字符。最后返回移除后的字符串
trim(x [,y])如果没有可选参数Y,该函数将移除参数X两侧的所有空格符。如果有参数Y,则移除X两侧的任意在Y中出现的字符。最后返回移除后的字符串
changes()返回最近执行的INSERT、UPDATE和DELETE语句所影响的数据行数
coalesce(x,y,…)返回函数参数中第一个非NULL的参数,如果参数都是NULL,则返回NULL
ifnull(x,y)返回第一个不为NULL的函数参数,如果两个均为NULL,则返回NULL
typeod(x)返回函数参数数据类型的字符串表示形式,如"Integer、text、real、null"等
nullif(x,y)如果x、y相等返回NULL,否则的话返回第一个参数x

三、时间和日期函数

SQLite 支持以下五个日期和时间函数:

函数名描述
date(timestring, modifier, modifier, …)以 YYYY-MM-DD 格式返回日期
time(timestring, modifier, modifier, …)以 HH:MM:SS 格式返回时间
datetime(timestring, modifier, modifier, …)以 YYYY-MM-DD HH:MM:SS 格式返回
julianday(timestring, modifier, modifier, …)返回从格林尼治时间的公元前 4714 年 11 月 24 日正午算起的天数
strftime(format, timestring, modifier, modifier, …)根据第一个参数指定的格式字符串返回格式化的日期

上述五个日期和时间函数把时间字符串作为参数。时间字符串后跟零个或多个 modifier 修饰符。strftime() 函数也可以把格式字符串 format 作为其第一个参数。

1. 时间字符串(timeString)

时间字符串可以采用下列的任意格式:

时间字符串实例
YYYY-MM-DD2019-04-20
YYYY-MM-DD HH:MM2019-04-20 22:43
YYYY-MM-DD HH:MM:SS2019-04-20 22:43:46
YYYYMMDD HHMMSS20190420 224346
YYYY-MM-DDTHH:MM2019-04-20 22:43:46
HH:MM:SS22:43:46
now2019-04-20
2. 修饰符(modifier)
修饰符描述
NNN days用于天数的调整,+1 day表示向后一天,-1 day表示向前一天
NNN hours用于小时的调整,+1 hour表示向后一小时,-1 hour表示向前一小时
NNN minutes用于分钟的调整,+1 minute表示向后一分钟,-1 minute表示向前一分钟
NNN.NNNN seconds用于秒的调整,+1 second表示向后一秒,-1 second表示向前一秒
NNN months用于月份的调整,+1 month表示向后一个月,-1 month表示向前一个月
NNN years用于年份的调整,+1 year表示向后一年,-1 year表示向前一年
start of month某一日期的当前月份
start of year某一日期的当前年份
start of day某一日期的当前天数
weekday N表示星期N,N取值为0~6,分别表示周日 ~ 周六
unixepochUNIX 时间戳
localtime本地时区的日期和时间
utc转化为UTC时间值
3. 格式化(format)

格式化是用于 strftime 函数的参数,可采用值如下:

格式描述
%d一月中的第几天,01-31
%f带小数部分的秒,SS.SSS
%H小时,00-23
%j一年中的第几天,001-366
%J儒略日数,DDDD.DDDD
%m月,00-12
%M分,00-59
%s从 1970-01-01 算起的秒数
%S秒,00-59
%w一周中的第几天,0-6 (0 is Sunday)
%W一年中的第几周,01-53
%Y年,YYYY
%%% symbol
4. 实例

计算当前月份的最后一天:

sqlite> SELECT date('now','start of month', '+1 month', '-1 day') AS last_day_of_this_month;
last_day_of_this_month
----------------------
2019-04-30

计算当年 10 月的第一个星期二的日期:

sqlite> SELECT date('now', 'start of year', '+9 month', 'weekday 2') AS october_first_tues;
october_first_tues
------------------
2019-10-01

计算从 2004 年某一特定时刻以来的秒数:

sqlite> SELECT strftime('%s', 'now')-strftime('%s', '2004-01-01 11:26:00') AS Count;
Count
----------
482817426

计算新中国成立以来至今的天数:

sqlite> SELECT julianday('now')-julianday('1949-10-01') AS China_Found_Day;
China_Found_Day
----------------
25403.6443211804

当前时间与UTC时间的转换:

sqlite> SELECT datetime('now', 'utc') AS UTC;
UTC
-------------------
2019-04-20 07:24:24

四、数据类型的比较和NULL值的处理

首先创建一个表 Test,然后插入任意的值,如下所示:

CREATE TABLE Test(whatever);
INSERT INTO Test VALUES('314159');
INSERT INTO Test VALUES(314159);
INSERT INTO Test VALUES(x'314159');
INSERT INTO Test VALUES(3.14159);
INSERT INTO Test VALUES(NULL);

我们在插入这些值之后,通过 SELECT 和 typeof 函数来查看我们插入的值:

SELECT whatever, typeof(whatever) 
FROM Test;
whatever    typeof(whatever)
----------  ----------------
314159      text
314159      integer
1AY         blob
3.14159     real
NULL        null

可以看到字段 whatever 没有添加任何约束,因此它可以存储不同的类。我们通过 typeof 函数也验证了它确实存储了不同的类,那这些不同的类之间是如何比较大小的呢?事实上它们遵循一定的规则:

  • NULL 存储类聚有最低的类值。一个具有 NULL 存储类的值比所有其他的值都小(包括其它具有 NULL 存储类的值)。在 NULL 值之间,没有具体的排序顺序。
  • integer 或 real 存储类值高于 NULL,它们的类值相等,integer 值和 real 值通过去数值进行比较。
  • text 存储类的值比 integer 和 real 高。数值永远比字符串的值低。当两个 text 值进行比较时,其大小由其值中定义的“排序法”决定。
  • blob 存储类具有最高的类值。具有 blob 类的值大于其他所有类的值。

所以当我们执行下列语句时,我们就能知道会得出什么结果了:

SELECT whatever, typeof(whatever) 
FROM Test 
ORDER BY whatever;
whatever    typeof(whatever)
----------  ----------------
NULL        null
3.14159     real
314159      integer
314159      text
1AY         blob

其结果与我们所说的规则一致。在了解了数据类型之间的比较之后,接下来我们来看到数据库中比较特殊的 NULL 值。

NULL值

NULL 值在 SQLite 中表示的是一种对“未知”或“不可知”概念的支持。NULL 是缺失信息的占位符,本身不是值。NULL 表示该位置没有值:NULL 不是什么其它值,NULL不是真,也不是假,不是零,也不是空字符串。在 SQLite 中,关于 NULL 有如下三条约定:

  1. 为了在逻辑表达式中使用 NULL,SQLite 使用了三态逻辑,NULL 是真假值之一。下表显示了 AND、OR 与 NULL 之间的关系:
xyx AND yx OR y
TrueTrueTrueTrue
TrueFalseFalseTrue
TrueNULLNULLTrue
FalseFalseFalseFalse
FalseNULLFalseNULL
NULLNULLNULLNULL
  1. 可以通过 IS NULL 或者 IS NOT NULL 操作符检测 NULL 是否存在。
  2. NULL 不等于其他值,包括 NULL,不可以将 NULL 与其他值进行比较,NULL 绝对不会大于或小于其他 NULL 值。

参考

SQLite学习手册(内置函数)

SQLite 日期 & 时间

《SQLite权威指南》

  • 第3章 sqlite中的sql
  • 第4章 sqlite中的高级sql

希望这篇文章对你有所帮助~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值