Skip to content

SQL 语法

SQL 是一门语言,任何语言都有规范的语法定义。 SQL 由 ISO/IEC SC 32 定义。不过 SQL 的具体实现由商业公司决定的,因此不同的数据库对 SQL 语言语法的支持也略微不同。

语言元素

SQL Element

上图显示了 SQL 语言的主要语言元素,其中包括:

  • 关键字(Keyword): 由 SQL 语言定义,他们是大小写不敏感的,尽管通常我们使用大写来表示
  • 标识符(Identifier): 用于表示数据库中的对象即架构、表、列等名称。标识符必须以字母(新的数据库通常也支持 Unicode 字母)和下划线开头,后续可以是字母、下划线、数字(SQL标准不能以数字结尾),标识符同样不区分大小写除非被双引号包围,甚至有些数据库中带双引号的标识符可用包含任意字符
  • 表达式(Expression): 用于生成标量值(scalar value),也可以生成由数据列和行组成的表,他们是语句操作的对象,可以由多种途径来构造表达式,例如字面量(literal values)、列值(column values)、null、变量(variables)等,他们还可以结合函数和运算符来构造新的表达式
  • 查询(Query): 用于根据特定条件(谓语)检索数据
  • 谓词(Predicate): 可计算为 SQL 3VL(true/false/null)的逻辑表达式,用于限制语句和查询的结果核心就是 WHERE 子句
  • 语句(statement): 他是狭义上的,特指对架构或数据产生持久性影响的语句,例如增删改。也包括事务控制、程序流等
  • 子句(clause): 是查询和语句的组成部分

而 SQL 语句由一系列命令(commands)组成,一条命令由一系列语句组成,最终由一个分号结束。而一个语句可以是关键字(keyword)、标识符(identifier)、带引号的标识符(a quoted identifier)、字面量(literal)、常量(constant)或特殊符号(a special character symbol)配合表达式来构成,每个语句之间通常使用空白符(空格、制表符、回车)分隔,如果没有歧义(通常只有在特殊符号与其他标记相邻时才会出现)也可以不需要空白符。

标识符和关键字

关键字就是 SQL 语句中具有特殊意义的词,像 SELECT FROM 等都属于关键字。关键字本身不区分大小写,但通常为了避免歧义通常写作大写形式:

SQL
-- 等价
UPDATE MY_TABLE SET A = 5;
uPDaTE my_TabLE SeT a = 5;
UPDATE my_table SET a = 5;
-- 为了避免歧义可用
UPDATE "my_table" SET "a" = 5;

标识符表示数据库(database)、表(table)、索引(index)、列(column)、别名(alias)、视图(view)、存储过程(stored procedure)等数据库对象的名字。标识符本身不需要携带引号,不使用引号包围的默认会被转换为小写形式。而如果希望写一个可移植的应用应该总是用引号修饰一个特定名字或者完全不使用双引号修饰。甚至如果标识符和关键字相同也可以使用双引号来修饰。

Tips

规范规定标识符使用双引号包围,比较特殊的就是 MySQL 中使用双引号来表示字符串,因此他使用 `my_table` 来标记标识符。在 MySQL 8 中引入了 ANSI_QUOTES 模式允许双引号引用标识符

字面量

主要是对于一些基本的数据类型的字面量进行讲解。

字符串

SQL 中的字符串字面量是由单引号括起来的任意字符序列,例如 'This is a string'。如果要在字符串中包含单引号可以连续输入两个单引号来转义例如 'Dianne''s house'

Tips

在 MySQL 中可以使用单引号和双引号都可以包围字符串,这和很多编程语言类似, 他可以使用 '' "" \' \" 来转义,以及单引号字符串中的双引号等形式不需要转义。在 MySQL 8 中引入了 ANSI_QUOTES 模式来只允许单引号字符串,符合 SQL 标准

MySQL 字符集

MySQL 对 Unicode 的支持非常曲折。在 MySQL 8 之前默认字符集是 latin1 如果包含中文就会导致乱码。因此通常会指定 utf8 字符集。在 MySQL 中 utf8 字符集包含两种:

  • utf8mb3: 阉割版的 utf8 字符集,只能使用 1~3 个字节表示字符
  • utf8mb4: 正宗的 utf8 字符集,使用 1~4 个字节表示字符

Tips

其中在 MySQL 8 之后默认的字符集改为 utf8mb4。还有就是可以直接使用 utf8 他默认是指向 utf8mb3。未来可能会更改并统一到 utf8mb4

数值

数值包括包括精确值(整数和 DECIMAL)以及近似值(浮点数):

Bash
digits
digits.[digits][e[+-]digits]
[digits].digits[e[+-]digits]
digitse[+-]digits

其中整数就是数字序列,如果包括小数点会解析为浮点数,数字前面可以有 +- 表示正负值(他可以看作是操作符)。还可以以科学计数法的形式表示浮点数。

布尔值

SQL 标准中规定了 TRUE 和 FALSE 两个布尔常量。

Tips

不区分大小写

日期和时间

标准 SQL 要求使用类型关键字和字符串来指定日期和时间文字:

SQL
-- 关键字和字符串之间的空格是可选的
DATE 'str'  -- str 推荐的格式是 YYYY-MM-DD
TIME 'str'  -- str 推荐的格式是 hh:mm:ss
TIMESTAMP 'str' -- str 推荐的格式是 YYYY-MM-DD hh:mm:ss 其中空格还可以使用 T 作为分割

Tips

推荐的就是遵循 ISO 8601 标准的时间类型

Tips

MySQL 中比较特殊的就是日期和时间在为空是会显示为 0000-00-00 00:00:00

空值

空用 NULL 表示。

注释

标准的 SQL 支持两种注释方式:

SQL
-- 单行注释
/*  多行
    注释
*/

-- MySQL 还支持 # 到行尾的注释方式
SELECT 1; # 只有 MySQL 支持

参考