详解SQLite中的数据类型


当前第2页 返回上一页

3.4 比较示例
 

CREATE TABLE t1(
  a TEXT,   -- text affinity
  b NUMERIC,  -- numeric affinity
  c BLOB,   -- no affinity
  d      -- no affinity
);
 
-- Values will be stored as TEXT, INTEGER, TEXT, and INTEGER respectively
INSERT INTO t1 VALUES('500', '500', '500', 500);
SELECT typeof(a), typeof(b), typeof(c), typeof(d) FROM t1;
text|integer|text|integer
 
-- Because column "a" has text affinity, numeric values on the
-- right-hand side of the comparisons are converted to text before
-- the comparison occurs.
SELECT a < 40,  a < 60,  a < 600 FROM t1;
0|1|1
 
-- Text affinity is applied to the right-hand operands but since
-- they are already TEXT this is a no-op; no conversions occur.
SELECT a < '40', a < '60', a < '600' FROM t1;
0|1|1
 
-- Column "b" has numeric affinity and so numeric affinity is applied
-- to the operands on the right. Since the operands are already numeric,
-- the application of affinity is a no-op; no conversions occur. All
-- values are compared numerically.
SELECT b < 40,  b < 60,  b < 600 FROM t1;
0|0|1
 
-- Numeric affinity is applied to operands on the right, converting them
-- from text to integers. Then a numeric comparison occurs.
SELECT b < '40', b < '60', b < '600' FROM t1;
0|0|1
 
-- No affinity conversions occur. Right-hand side values all have
-- storage class INTEGER which are always less than the TEXT values
-- on the left.
SELECT c < 40,  c < 60,  c < 600 FROM t1;
0|0|0
 
-- No affinity conversions occur. Values are compared as TEXT.
SELECT c < '40', c < '60', c < '600' FROM t1;
0|1|1
 
-- No affinity conversions occur. Right-hand side values all have
-- storage class INTEGER which compare numerically with the INTEGER
-- values on the left.
SELECT d < 40,  d < 60,  d < 600 FROM t1;
0|0|1
 
-- No affinity conversions occur. INTEGER values on the left are
-- always less than TEXT values on the right.
SELECT d < '40', d < '60', d < '600' FROM t1;
1|1|1

若示例中的比较被替换——例如"a<40"被写作"40>a"——所有的结果依然相同相同。
4.0 操作符

所有的数学运算符(+, -, *, /, %, <<, >>, &, and |)在展开前会将两个操作数放入 NUMERIC 储存类。即使这个过程是有损和不可逆转的。一个 NULL 操作数在数学运算符上产生一个 NULL 结果。在数算运算符上的操作数不被视为数字,NULL 并不会被转为0或0.0。

5.0 排序, 分组 和 组合查询

当查询结果使用 ORDER BY 子句排序时, 存储类型的NULL空值是排在第一位的, 其次是INTEGER和散布在数字顺序的REAL数据, 其次是按照核对序列顺序的TEXT值, 最后为memcmp() order 的BLOB值. 排序之前不会出现任何存储类型转换.

当使用GROUP BY 子句分组时不同类型的值被认为是不同的数据, 除了INTEGER 和 REAL 值如果他们数值相等则被认为是相同的的数据. 没有任何亲和性适用于GROUP BY 子句结果的任意值.

组合查询使用 UNION, INTERSECT 和 EXCEPT 在数据之间执行隐式的比较. 没有任何亲和性适用于与UNION, INTERSECT, 或者 EXCEPT关联的隐式比较的运算数  - 数据的比较就像这样.

6.0 整理序列

当 SQLite 比较两个字符串时,它使用一个整理序列或整理函数(一物两表)来决定当两个字符串相同时,哪个字符串值更高。SQLite 拥有三个内建整理函数:BINARY, NOCASE, 和 RTRIM。

  •     BINARY - 使用 memcmp() 比较字符串,无视文本编码。
  •     NOCASE - 与二进制比较相同,除了 ASCII 的26个大写字母在比较前将会转为其小写形势。注意,只有 ASCII 字符会大小写转化。 由于表大小的需求,SQLite 并不会尝试 UTF 大小写转化。
  •     RTRIM - 与二进制比较相同,除了尾部空格符将被忽略。

应用可以通过 sqlite3_create_collation() 接口注册额外的整理函数。

6.1 设定SQL中的排列顺序

每个表中的每一个列都具有一个相关的排序函数。如果没有显式地定义排序函数,那么,就会缺省使用BINARY作为排序函数。列定义中的COLLATE子句可为列定义一个可选的排序函数。

对于二元比较运算符(=, <, >, <=, >=, !=, IS, and IS NOT)来说,判定到底使用哪个排序函数的规则按顺序如下所列:

  •     如果两个操作数中有任意一个操作数具有使用后缀COLLATE运算符显式定义的排序函数,那么就会用该函数进行比较,如果两个操作数都有的情况下,优先使用左操作数的排序函数。
  •     如果两个操作数中任意一个操作数是一个列,那么就会使用该列的排序函数进行比较,但在两个操作数都是列的情况下,优先使用左操作数对应的列的排序函数。为了达到这句话的目的,列名前带有1个或多个一元运算符"+"的,仍然按原列名处理。
  •     其它情况下,采用BINARY排序函数进行比较。

比较运算中的操作数,如果在它的任何子表达式中使用了后缀 COLLATE运算符,就可以认为是具有显式的排序函数(上文中的规则1)。 再者,如果在比较表达式中的任何地方使用了 COLLATE运算符,那么该运算符所定义的排序函数就会用于字符串的比较,而无论在表达式中出现了表中的哪一列。如果在比较中的任何地方出现了两个或多个 COLLATE运算符子表达式,无论在表达式中嵌入得多深,也无论表达式是怎么使用括号的,都会使用出现在最左侧的显式排序函数。

表达式"x BETWEEN y and z"从逻辑上讲,同"x >= y AND x <= z"这两个比较运算完全等价,在使用排序函数时它们俩要象两个本来就是独立的比较运算一样进行处理。在判定排列顺序时,表达式"x IN (SELECT y ...)"处理方式完全同表达式"x = y"一样,形如"x IN (y, z, ...)"的表达式,排列顺序完全同X的排列顺序一样。

作为 SELECT语句的一个部分,ORDER BY子句中排序条件也可以通过使用COLLATE运算符设定排列顺序,如果设定了排序时就要按照设定的排序函数进行排序。否则,如果ORDER BY子句使用的排序表达式是一个列,那么该列的排列顺序就用于判定排列顺序。如果该排序表达式不是列并且也无COLLATE子句,就会使用BINARY排列顺序。

6.2 整理序列示例

下面的示例将识别整理序列,决定 SQL 语句的文本比较结果。注意,在文本比较时,如果是数字,二进制或Null值,整理序列可能并没有被使用。
 

CREATE TABLE t1(
  x INTEGER PRIMARY KEY,
  a,         /* collating sequence BINARY */
  b COLLATE BINARY, /* collating sequence BINARY */
  c COLLATE RTRIM,  /* collating sequence RTRIM */
  d COLLATE NOCASE  /* collating sequence NOCASE */
);
          /* x  a   b   c    d */
INSERT INTO t1 VALUES(1,'abc','abc', 'abc ','abc');
INSERT INTO t1 VALUES(2,'abc','abc', 'abc', 'ABC');
INSERT INTO t1 VALUES(3,'abc','abc', 'abc ', 'Abc');
INSERT INTO t1 VALUES(4,'abc','abc ','ABC', 'abc');
 
/* a=b 的文本比较表现为使用 BINARY (二进制)整理序列。 */
SELECT x FROM t1 WHERE a = b ORDER BY x;
--结果 1 2 3
 
/* a=b 的文本比较表现为使用 RTRIM 整理序列。 */
SELECT x FROM t1 WHERE a = b COLLATE RTRIM ORDER BY x;
--结果 1 2 3 4
 
/* d=a 的文本比较表现为使用 NOCASE 整理序列。 */
SELECT x FROM t1 WHERE d = a ORDER BY x;
--结果 1 2 3 4
 
/* a=d 的文本比较表现为使用 BINARY (二进制)整理序列。 */
SELECT x FROM t1 WHERE a = d ORDER BY x;
--结果 1 4
 
/* 'abc'=c 的文本比较表现为使用 RTRIM (二进制)整理序列。 */
SELECT x FROM t1 WHERE 'abc' = c ORDER BY x;
--结果 1 2 3
 
/* c='abc' 的文本比较表现为使用 RTRIM 整理序列。 */
SELECT x FROM t1 WHERE c = 'abc' ORDER BY x;
--结果 1 2 3
 
/* 分组表现为使用 NOCASE 整理序列(值'abc','ABC' 和 'Abc'
** 被分为同一组)。*/
SELECT count(*) FROM t1 GROUP BY d ORDER BY 1;
--结果 4
 
/* 分组表现为使用 BINARY 整理序列(值'abc','ABC' 和 'Abc'
** 被分为不同的组)。*/
SELECT count(*) FROM t1 GROUP BY (d || '') ORDER BY 1;
--结果 1 1 2
 
/* 列c排序表现为使用 RTRIM 整理序列。*/(译注:sorting or column c 疑为 sorting of...误写)
SELECT x FROM t1 ORDER BY c, x;
--结果 4 1 2 3
 
/* (c||'')排序表现为使用 BINARY 整理序列。*/
SELECT x FROM t1 ORDER BY (c||''), x;
--结果 4 2 3 1
 
/* 列c排序表现为使用 NOCASE 整理序列。*/
SELECT x FROM t1 ORDER BY c COLLATE NOCASE, x;
--结果 2 4 3 1


标签:SQLite

返回前面的内容

相关阅读 >>

Sqlite教程(十二):锁和并发控制详解

python的消息队列包snakemq使用初探

android学习笔记-保存数据到sql数据库中(saving data in sql databases)

Sqlitemanager怎么激活Sqlite数据库管理软件激活图文教程

Sqlite 入门教程一 基本控制台(终端)命令

易语言操作edb数据库的方法

如何通过android stduio来编写一个完整的天气预报app

深入Sqlite多线程的使用总结详解

qt数据库相关应用开发总结

beego中orm操作各类数据库连接方式详细示例

更多相关阅读请进入《Sqlite》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...