SQLite 理解这些运算符,按优先级1顺序排列
(从上到下 / 从最高到最低)
运算符 2 |
---|
~ [expr] + [expr] - [expr] |
[expr] COLLATE (collation-name) 3 |
|| -> ->> |
* / % |
+ - |
& | << >> |
[expr] ESCAPE [escape-character-expr] 4 |
< > <= >= |
= == <> != IS IS NOT IS DISTINCT FROM IS NOT DISTINCT FROM [expr] BETWEEN5 [expr] AND [expr] IN5 MATCH5 LIKE5 REGEXP5 GLOB5 [expr] ISNULL [expr] NOTNULL [expr] NOT NULL |
NOT [expr] |
AND |
OR |
COLLATE 运算符是将 排序规则 分配给表达式的单目后缀运算符。COLLATE 运算符设置的排序规则会覆盖表 列定义 中 COLLATE 子句确定的排序规则。有关排序规则的更多信息,请参阅 SQLite3 中的数据类型 文档中的 排序规则详细讨论。
单目运算符+是一个无操作运算符。它可以应用于字符串、数字、BLOB 或 NULL,并且始终返回与操作数具有相同值的返回值。
请注意,等于和不等于运算符有两种变体。等于可以是=或==. 不等于运算符可以是!=或<>. 该||运算符是“连接” - 它将操作数的两个字符串连接在一起。该->和->>运算符是“提取”;它们从左侧提取右侧组件。例如,请参阅 JSON 子组件提取。
该%运算符 强制转换 它的两个操作数为 INTEGER 类型,然后计算左整数除以右整数后的余数。如果两个操作数都是整数并且不会发生溢出,则其他算术运算符执行整数运算;如果两个操作数之一是实数值,或者整数运算会导致溢出,则执行浮点运算。根据 IEEE 标准 754 进行浮点运算。整数除法会产生一个整数结果,向零截断。
任何二元运算符的结果都是数值或 NULL,除了||连接运算符,以及->和->>提取运算符,它们可以返回任何类型的值。
通常,当任何操作数为 NULL 时,所有运算符都计算为 NULL,但以下列出的特定情况除外。这符合 SQL92 标准。
与 NULL 配对时
AND当另一个操作数为假时,计算为 0(假);当另一个操作数为真时,计算为 1(真)。
OR计算为
该IS和IS NOT运算符的工作原理类似于=和!=,但一个或两个操作数为 NULL 时除外。在这种情况下,如果两个操作数都是 NULL,则 IS 运算符计算为 1(真),IS NOT 运算符计算为 0(假)。如果一个操作数为 NULL,另一个操作数不为 NULL,则 IS 运算符计算为 0(假),IS NOT 运算符计算为 1(真)。IS 或 IS NOT 表达式不可能计算为 NULL。
该IS NOT DISTINCT FROM运算符是IS运算符的另一种写法。同样,该IS DISTINCT FROM运算符的意思与IS NOT相同。标准 SQL 不支持紧凑的 IS 和 IS NOT 表示法。这些紧凑形式是 SQLite 的扩展。您必须在其他 SQL 数据库引擎上使用冗长且可读性差的 IS NOT DISTINCT FROM 和 IS DISTINCT FROM 运算符。
字面值表示一个常量。字面值可以是整数、浮点数、字符串、BLOB 或 NULL。
以下图表显示了整数和浮点字面值(统称为“数值字面值”)的语法
如果数值字面值具有小数点或指数化子句,或者小于 -9223372036854775808 或大于 9223372036854775807,则它是一个浮点字面值。否则,它是一个整数字面值。浮点字面值指数化子句开头的“E”字符可以是大写或小写。即使区域设置将“,”指定为此角色,"." 字符也始终用作小数点 - 使用 "," 作为小数点会导致语法歧义。
从 SQLite 版本 3.46.0(2024-05-23)开始,可以在任何两个数字之间添加一个额外的下划线("_")字符。下划线纯粹是为了人类的可读性,SQLite 会忽略它们。
十六进制整数字面值遵循 C 语言的“0x”或“0X”后跟十六进制数字的表示法。例如,0x1234 与 4660 相同,0x8000000000000000 与 -9223372036854775808 相同。十六进制整数字面值被解释为 64 位补码整数,因此精度限制在十六位有效数字。对十六进制整数的支持已添加到 SQLite 版本 3.8.6(2014-08-15)中。为了向后兼容,只有 SQL 语言解析器能理解“0x”十六进制整数表示法,而类型转换例程不能理解。由于 CAST 表达式 或 列亲和性 转换,或者在执行数字运算之前或在执行任何其他运行时转换之前,包含格式类似于十六进制整数的文本的字符串变量不会被解释为十六进制整数。当将格式为十六进制整数的字符串值强制转换为整数时,转换过程会在遇到“x”字符时停止,因此生成的整数始终为零。只有当十六进制整数表示法出现在 SQL 语句文本中时,SQLite 才能理解它,而当它作为数据库内容的一部分出现时,SQLite 则无法理解。
字符串常量是通过将字符串括在单引号(')中来形成的。字符串中的单引号可以通过连续放置两个单引号来编码 - 就像在 Pascal 中一样。不支持使用反斜杠字符的 C 样式转义,因为它们不是标准 SQL。
BLOB 字面值是包含十六进制数据的字符串字面值,前面有一个“x”或“X”字符。例如:X'53514C697465'
字面值也可以是标记“NULL”。
“变量”或“参数”标记在表达式中指定了一个占位符,该占位符将使用 sqlite3_bind() 系列的 C/C++ 接口在运行时填充值。参数可以采用多种形式
?NNN 问号后跟数字 NNN 为第 NNN 个参数保留一个位置。NNN 必须介于 1 和 SQLITE_MAX_VARIABLE_NUMBER 之间。 ? 不带数字的问号会创建一个参数,其编号比已分配的最大参数编号大 1。如果这意味着参数编号大于 SQLITE_MAX_VARIABLE_NUMBER,则会发生错误。为了与其他数据库引擎兼容,提供了这种参数格式。但是,由于很容易误数问号,因此不建议使用这种参数格式。建议程序员改用以下符号格式之一或上面的 ?NNN 格式。 :AAAA 冒号后跟标识符名称将为名称为 :AAAA 的 命名参数 保留一个位置。命名参数也有编号。分配的编号比已分配的最大参数编号大 1。如果这意味着参数将被分配一个大于 SQLITE_MAX_VARIABLE_NUMBER 的编号,则会发生错误。为避免混淆,最好避免混合使用命名参数和编号参数。 @AAAA “at”符号与冒号的功能完全相同,只是创建的参数名称为 @AAAA。 $AAAA 美元符号后跟标识符名称也为名称为 $AAAA 的命名参数保留一个位置。在这种情况下,标识符名称可以包含一个或多个“::”出现以及包含任何文本的“(...)”中的后缀。这种语法是 Tcl 编程语言 中变量名的形式。这种语法的存在是因为 SQLite 实际上是 Tcl 扩展,它已经逃脱到野外。
未使用 sqlite3_bind() 分配值的参数将被视为 NULL。可以使用 sqlite3_bind_parameter_index() 接口将符号参数名转换为等效的数字索引。
最大参数编号在编译时由 SQLITE_MAX_VARIABLE_NUMBER 宏设置。单个 数据库连接 D 可以使用 sqlite3_limit(D, SQLITE_LIMIT_VARIABLE_NUMBER,...) 接口将最大参数编号降低到编译时最大值以下。
LIKE 运算符执行模式匹配比较。LIKE 运算符右侧的操作数包含模式,左侧操作数包含要与模式匹配的字符串。LIKE 模式中的百分号(“%”)匹配字符串中的任何零个或多个字符序列。LIKE 模式中的下划线(“_”)匹配字符串中的任何单个字符。任何其他字符都匹配自身或其大小写等效字符(即不区分大小写的匹配)。重要说明:默认情况下,SQLite 仅了解 ASCII 字符的大小写。LIKE 运算符在默认情况下对超出 ASCII 范围的 Unicode 字符区分大小写。例如,表达式 'a' LIKE 'A' 为 TRUE,但 'æ' LIKE 'Æ' 为 FALSE。SQLite 的 ICU 扩展包含 LIKE 运算符的增强版本,它可以对所有 Unicode 字符执行大小写折叠。
如果可选的 ESCAPE 子句存在,那么 ESCAPE 关键字后面的表达式必须计算为一个包含单个字符的字符串。此字符可以在 LIKE 模式中使用,以包含字面百分号或下划线字符。转义字符后跟百分号 (%)、下划线 (_) 或第二个转义字符本身分别匹配字面百分号、下划线或单个转义字符。
中缀 LIKE 运算符通过调用应用程序定义的 SQL 函数 like(Y,X) 或 like(Y,X,Z) 来实现。
LIKE 运算符可以使用 case_sensitive_like pragma 设为区分大小写。
GLOB 运算符类似于 LIKE,但使用 Unix 文件通配符语法作为其通配符。此外,GLOB 区分大小写,而 LIKE 不区分大小写。GLOB 和 LIKE 都可以以 NOT 关键字开头,以反转测试的含义。中缀 GLOB 运算符通过调用函数 glob(Y,X) 来实现,并且可以通过覆盖该函数来修改。
REGEXP 运算符是 regexp() 用户函数的特殊语法。默认情况下没有定义 regexp() 用户函数,因此使用 REGEXP 运算符通常会导致错误消息。如果在运行时添加了一个名为“regexp”的 应用程序定义的 SQL 函数,那么“X REGEXP Y”运算符将被实现为对“regexp(Y,X)”的调用。
MATCH 运算符是 match() 应用程序定义函数的特殊语法。默认的 match() 函数实现会引发异常,对于任何事情都不真正有用。但扩展可以覆盖 match() 函数,使其具有更有用的逻辑。
提取运算符充当函数“->”() 和“->>”() 的特殊语法。这些函数的默认实现执行 JSON 子组件提取,但扩展可以覆盖它们以用于其他目的。
BETWEEN 运算符在逻辑上等效于一对比较。“x BETWEEN y AND z”等效于“x>=y AND x<=z”,但使用 BETWEEN 时,x 表达式只计算一次。
CASE 表达式在其他编程语言中的作用类似于 IF-THEN-ELSE。
CASE 关键字和第一个 WHEN 关键字之间出现的可选表达式称为“基”表达式。CASE 表达式有两种基本形式:一种带基表达式,另一种不带基表达式。
在没有基表达式的 CASE 中,每个 WHEN 表达式都会被计算,并将结果视为布尔值,从最左侧开始,一直到最右侧。CASE 表达式的结果是对应于第一个计算结果为真的 WHEN 表达式的 THEN 表达式的计算结果。或者,如果所有 WHEN 表达式的计算结果都不为真,则为 ELSE 表达式的计算结果(如果有)。如果不存在 ELSE 表达式,并且所有 WHEN 表达式的计算结果都不为真,则总体结果为 NULL。
计算 WHEN 项时,NULL 结果被认为是不真实的。
在带基表达式的 CASE 中,基表达式只计算一次,并将结果与从左到右计算的每个 WHEN 表达式的结果进行比较。CASE 表达式的结果是对应于第一个比较结果为真的 WHEN 表达式的 THEN 表达式的计算结果。或者,如果所有 WHEN 表达式的计算结果都不等于基表达式,则为 ELSE 表达式的计算结果(如果有)。如果不存在 ELSE 表达式,并且所有 WHEN 表达式的计算结果都不等于基表达式,则总体结果为 NULL。
当将基表达式与 WHEN 表达式进行比较时,应用相同的排序规则、亲和力和 NULL 处理规则,就像基表达式和 WHEN 表达式分别是运算符的左操作数和右操作数一样=运算符。
如果基表达式为 NULL,则 CASE 的结果始终是 ELSE 表达式的计算结果(如果存在),或者 NULL(如果不存在)。
两种形式的 CASE 表达式都使用惰性或短路计算。
以下两个 CASE 表达式的唯一区别是,在第一个示例中,x 表达式只计算一次,而在第二个示例中,x 表达式可能会被计算多次
内置的 iif(x,y,z) SQL 函数 在逻辑上等效于“CASE WHEN x THEN y ELSE z END”。iif() 函数存在于 SQL Server 中,并包含在 SQLite 中以实现兼容性。一些开发人员更喜欢 iif() 函数,因为它更简洁。
IN 和 NOT IN 运算符在左侧接受一个表达式,在右侧接受一个值列表或子查询。当 IN 或 NOT IN 运算符的右操作数是一个子查询时,子查询必须与左侧操作数的 行值 中的列数相同。如果左侧表达式不是 行值 表达式,则 IN 或 NOT IN 运算符右侧的子查询必须是标量子查询。如果 IN 或 NOT IN 运算符的右操作数是一个值列表,则这些值中的每一个都必须是标量,并且左侧表达式也必须是标量。IN 或 NOT IN 运算符的右侧可以是表 name 或 表值函数 name,在这种情况下,右侧被理解为形式为“(SELECT * FROM name)”的子查询。当右操作数为空集时,IN 的结果为假,NOT IN 的结果为真,无论左操作数是什么,即使左操作数为 NULL 也一样。
IN 或 NOT IN 运算符的结果由以下矩阵决定
左操作数
为 NULL右操作数
包含 NULL右操作数
为空集左操作数找到
在右操作数内IN 运算符的
结果IN 运算符的
NOT IN 运算符的结果 结果 结果 结果 否 假 真 结果 无关紧要 结果 否 假 结果 真 结果 无关紧要 假 否 结果 无关紧要 结果 结果 是 是 无关紧要 真 结果 真 是 是
NULL
9. 表列名
10. EXISTS 运算符
EXISTS 运算符始终计算为整数 0 和 1 之一。如果执行作为 EXISTS 运算符的右操作数指定的 SELECT 语句会返回一行或多行,则 EXISTS 运算符计算为 1。如果执行 SELECT 语句不会返回任何行,则 EXISTS 运算符计算为 0。
11. 子查询表达式
包含在圆括号中的 SELECT 语句是一个子查询。所有类型的 SELECT 语句,包括聚合和复合 SELECT 查询(包含 UNION 或 EXCEPT 等关键字的查询),都允许作为标量子查询。子查询表达式的值为封闭的 SELECT 语句返回的结果的第一行。如果封闭的 SELECT 语句不返回任何行,则子查询表达式的值为 NULL。
12. 关联子查询
13. CAST 表达式
形式为“CAST(expr AS type-name)”的 CAST 表达式用于将 expr 的值转换为由 type-name 指定的不同 存储类别。CAST 转换类似于将 列亲和力 应用于值时发生的转换,但使用 CAST 运算符时,转换始终发生,即使转换是有损且不可逆的,而列亲和力只会在更改无损且可逆时更改值的 datatype。
如果 expr 的值为 NULL,则 CAST 表达式的结果也为 NULL。否则,结果的存储类别由将 确定列亲和力的规则 应用于 type-name 来确定。 type-name 的亲和力转换处理 NONE 将值转换为没有亲和力的 type-name 会导致该值被转换为 BLOB。转换为 BLOB 包括首先将值转换为数据库连接的 编码 中的 TEXT,然后将生成的字节序列解释为 BLOB 而不是 TEXT。 TEXT 将 BLOB 值转换为 TEXT 时,构成 BLOB 的字节序列被解释为使用数据库编码编码的文本。
将 INTEGER 或 REAL 值转换为 TEXT 会像通过 sqlite3_snprintf() 一样呈现该值,只是生成的 TEXT 使用数据库连接的 编码。 REAL 将 BLOB 值转换为 REAL 时,该值首先被转换为 TEXT。
将 TEXT 值转换为 REAL 时,会从 TEXT 值中提取可以解释为实数的最长可能的文本前缀,并将其余部分忽略。从 TEXT 转换为 REAL 时,会忽略 TEXT 值中的任何前导空格。如果没有可以解释为实数的前缀,则转换的结果为 0.0。 INTEGER 将 TEXT 值转换为 INTEGER 时,会从 TEXT 值中提取可以解释为整数的最长可能前缀,并忽略其余部分。从 TEXT 转换为 INTEGER 时,TEXT 值中的任何前导空格都会被忽略。如果不存在可以解释为整数的前缀,则转换结果为 0。如果前缀整数大于 +9223372036854775807,则转换结果为 +9223372036854775807。类似地,如果前缀整数小于 -9223372036854775808,则转换结果为 -9223372036854775808。
转换为 INTEGER 时,如果文本看起来像带有指数的浮点数,则指数将被忽略,因为它不是整数前缀的一部分。例如,"CAST('123e+5' AS INTEGER)" 的结果是 123,而不是 12300000。
CAST 运算符只理解十进制整数 - 十六进制整数 的转换在十六进制整数字符串的 "0x" 前缀中的 "x" 处停止,因此 CAST 的结果始终为零。
将 REAL 值转换为 INTEGER 会产生 REAL 值与零之间最接近 REAL 值的整数。如果 REAL 大于最大的可能带符号整数 (+9223372036854775807),则结果为最大的可能带符号整数;如果 REAL 小于最小的可能带符号整数 (-9223372036854775808),则结果为最小的可能带符号整数。
在 SQLite 版本 3.8.2 (2013-12-06) 之前,将大于 +9223372036854775807.0 的 REAL 值转换为整数会导致产生最小的负整数,即 -9223372036854775808。这种行为旨在模拟 x86/x64 硬件在执行等效转换时的行为。
NUMERIC 将 TEXT 或 BLOB 值转换为 NUMERIC 会产生 INTEGER 或 REAL 结果。如果输入文本看起来像整数(没有小数点或指数)并且值足够小以适合 64 位带符号整数,则结果将是 INTEGER。看起来像浮点数的输入文本(有小数点和/或指数)并且该文本描述的值可以无损地转换为 IEEE 754 64 位浮点数和 51 位带符号整数之间,则结果为 INTEGER。(在上一句话中,指定了 51 位整数,因为这比 IEEE 754 64 位浮点数尾数的长度少一位,因此为文本到浮点数转换操作提供了 1 位的裕量。)任何描述超出 64 位带符号整数范围的值的文本输入都会产生 REAL 结果。 将 REAL 或 INTEGER 值转换为 NUMERIC 是一种无操作,即使 REAL 值可以无损地转换为整数。
请注意,将任何非 BLOB 值转换为 BLOB 的结果,以及将任何 BLOB 值转换为非 BLOB 值的结果可能会有所不同,具体取决于数据库 编码 是 UTF-8、UTF-16be 还是 UTF-16le。
SQL 语言在几个上下文中使用表达式并将其结果转换为布尔值(真或假)。这些上下文是
为了将 SQL 表达式的结果转换为布尔值,SQLite 首先将结果转换为 NUMERIC 值,方法与 CAST 表达式 相同。数字零值(整数 0 或实数 0.0)被认为是假。NULL 值仍然是 NULL。所有其他值都被认为是真。
例如,值 NULL、0.0、0、'english' 和 '0' 都被认为是假。值 1、1.0、0.1、-0.1 和 '1english' 被认为是真。
从 SQLite 3.23.0 (2018-04-02) 开始,SQLite 识别标识符 "TRUE" 和 "FALSE" 作为布尔文字,当且仅当这些标识符没有被用于其他含义时。如果已经存在名为 TRUE 或 FALSE 的列、表或其他对象,则为了向后兼容,TRUE 和 FALSE 标识符将引用这些其他对象,而不是布尔值。
布尔标识符 TRUE 和 FALSE 通常只是整数 1 和 0 的别名。但是,如果 TRUE 或 FALSE 出现在 IS 运算符的右侧,则 IS 运算符将左操作数评估为布尔值并返回适当的答案。
SQLite 支持许多 简单、聚合 和 窗口 SQL 函数。为了便于展示,简单函数进一步细分为 核心函数、日期时间函数、数学函数 和 JSON 函数。应用程序可以使用 sqlite3_create_function() 接口添加用 C/C++ 编写的新的函数。
上面的主要表达式气泡图显示了所有函数调用的单一语法。但这仅仅是为了简化表达式气泡图。实际上,每种类型的函数都有稍微不同的语法,如下所示。主要表达式气泡图中显示的函数调用语法是这里显示的三个语法的并集
OVER 子句对于 窗口函数 是必需的,在其他情况下则禁止使用。DISTINCT 关键字和 ORDER BY 子句只允许在 聚合函数 中使用。FILTER 子句不能出现在 简单函数 上。
可以使聚合函数和简单函数具有相同的名称,只要两种形式的函数的参数数量不同即可。例如,带有一个参数的 max() 函数是一个聚合函数,而带有两个或多个参数的 max() 函数是一个简单函数。聚合函数通常也可以用作窗口函数。
本页上次修改于 2024-06-02 10:08:16 UTC