Appearance
SQL 语法
系统 SQL 解析器:完整的 SQL 解析器,系统语法主要参考MySQL 规范。
语句表示可以使用 SQL 执行的各种操作。每种类型的语句都有自己的语法和用法详细信息,这些语法和用法详细信息单独描述如下所示:
文档符号解释
- <...>:
<>
表示该占位符必填 - [...]:
[]
表示该占位符选填 - UPPERCASE: 大写,表示该字段为关键字
示例
sql
SELECT <select_expr>[, select_expr] -- 至少需要一个 select_expr
[FROM <table_expr>] -- 选填
以上 SQL 表示至少需要一个 select_expr, [FROM <table_expr>]
是选填,如果存在 FROM
,那么 table_expr 也是必填,以下 SQL 都能满足以上定义:
SELECT select_expr
SELECT select_expr, select_expr2
SELECT select_expr FROM tableName
SELECT select_expr, select_expr2 FROM tableName
空白
SQL 语句的语法结构部分之间(标识符之间、部分符号之间、包括 SQL 的起始和结束)可以有任意的空白字符,这些空字符类型包括:空格字符,tab 制表符,换行符,CR 符,换页符等。
注释
支持 SQL 风格的注释:
- SQL 风格的注释以
--
开始,直到行末,--
后紧跟的空格可以忽略
关键字
以下场景的关键字是大小写不敏感的:
- 标准 SQL。例如,
SELECT
,select
和SeLeCt
都是允许的 - 在某些流行的 RDBMS 中被实现的关键字,例如,
DateTime
和datetime
是一样的
你可以在系统配置中检查某个数据类型的名称是否是大小写敏感型。
标识符
标识符包括:
- 集群、数据库、表、分区、列的名称
- 函数
- 数据类型
- 表达式别名
变量名可以被括起或不括起,后者是推荐做法。
没有括起的变量名,必须匹配正则表达式 ^[a-zA-Z_][0-9a-zA-Z_]*$
,并且不能和关键字
相同,合法的标识符名称:x
,_1
,X_y__Z123_
等。
如果想使用和关键字同名的变量名称,或者在变量名称中包含其它符号,你需要通过双引号或反引号,例如: "id"
, `id`
字符
字符包含数字,字母,括号,NULL 值等字符。
数字
数字类型字符会被做如下解析:
首先,当做 64 位的有符号整数,使用函数 strtoull
如果失败,解析成 64 位无符号整数,同样使用函数 strtoull
如果还失败了,试图解析成浮点型数值,使用函数 strtod
最后,以上情形都不符合时,返回异常
数字类型的值类型为能容纳该值的最小数据类型。
例如:1 解析成 UInt8
型,256 则解析成 UInt16
。
例如:1
, 18446744073709551615
, 0xDEADBEEF
, 01
, 0.1
, 1e100
, -1e-100
, inf
, nan
.
字符串
只支持用单引号包含的字符串。特殊字符可通过反斜杠进行转义。下列转义字符都有相应的实际值: \b
, \f
, \r
, \n
, \t
, \0
, \a
, \v
, \xHH
。其它情况下,以 \c
形式出现的转义字符,当c
表示任意字符时,转义字符会转换成c
。这意味着你可以使用 \'
和\\
。该值将拥有String
类型。
在字符串中,你至少需要对 '
和 \
进行转义。单引号可以使用单引号转义,例如 'It\'s'
和 'It''s'
是相同的。
复合字符串
数组都是使用方括号进行构造 [1, 2, 3]
,元组则使用圆括号 (1, 'Hello, world!', 2)
从技术上来讲,这些都不是字符串,而是包含创建数组和元组运算符的表达式。
创建一个数组必须至少包含一个元素,创建一个元组至少包含 2 个元素
当元组出现在 SELECT
查询的 IN
部分时,是一种例外情形。查询结果可以包含元组,但是元组类型不能保存到数据库中引擎)
NULL 值
代表不存在的值。
为了能在表字段中存储 NULL 值,该字段必须声明为 空值
类型。
根据数据的格式(输入或输出),NULL 值有不同的表现形式。更多信息参见文档
在处理 NULL
时存在很多细微差别。例如,比较运算的至少一个参数为 NULL
,则该结果也是 NULL
。与之类似的还有乘法运算,加法运算,以及其它运算。更多信息,请参阅每种运算的文档部分。
在语句中,可以通过 IS NULL 以及 IS NOT NULL 运算符,以及 isNull
、 isNotNull
函数来检查 NULL
值
函数
函数调用的写法,类似于一个标识符后接被圆括号包含的参数列表(可能为空)。与标准 SQL 不同,圆括号是必须的,不管参数列表是否为空。例如: now()
。
函数分为常规函数和聚合函数(参见Aggregate functions)。有些聚合函数包含 2 个参数列表,第一个参数列表中的参数被称为“parameters”。不包含“parameters”的聚合函数语法和常规函数是一样的。
运算符
在查询解析阶段,运算符会被转换成对应的函数,使用时请注意它们的优先级。例如:
表达式 1 + 2 * 3 + 4
会被解析成 plus(plus(1, multiply(2, 3)), 4)
.
数据类型及数据库/表引擎
CREATE
语句中的数据类型和表引擎写法与变量或函数类似。
换句话说,它们可以包含或不包含用括号包含的参数列表。更多信息,参见Create。
表达式别名
别名是用户对表达式的自定义名称
sql
expr AS alias
AS
— 用于定义别名的关键字。可以对表或 select 语句中的列定义别名 (AS
可以省略)
例如,SELECT table_name_alias.column_name FROM table_name table_name_alias
.expr
— 任意合法的表达式。例如,
SELECT column_name * 2 AS double FROM some_table
.alias
—expr
的名称。别名必须符合标识符
语法。例如,
SELECT "table t".column_name FROM table_name AS "table t"
.
用法注意
别名在当前查询或子查询中是全局可见的,你可以在查询语句的任何位置对表达式定义别名
别名在当前查询的子查询及不同子查询中是不可见的。例如,执行如下查询 SQL:
SELECT (SELECT sum(b.a) + num FROM b) - a.a AS num FROM a
,会提示异常Unknown identifier: num
.如果给 select 子查询语句的结果列定义其别名,那么在外层可以使用该别名。例如,
SELECT n + m FROM (SELECT 1 AS n, 2 AS m)
.注意列的别名和表的别名相同时的情形,考虑如下示例:
sqlCREATE TABLE t ( a Int, b Int )
sqlSELECT argMax(a, b), sum(b) AS b FROM t
textUnknown column 'a' in field list
在这个示例中,先声明了表
t
以及列b
。然后,在查询数据时,又定义了别名sum(b) AS b
。由于别名是全局的,使用表达式sum(b)
来替换表达式argMax(a, b)
中的变量b
。这种替换导致出现异常。如果对表名做了别名,那么在查询中使用该表时,必须使用别名,否则会报错。
这样的查询是正确的:
sqlSELECT t.a FROM table_name AS t WHERE t.a > 10
这样的查询是错误的:
sqlSELECT table_name.a FROM table_name AS t WHERE table_name.a > 10
textUnknown column 'table_name.a' in field list
在这个示例中,表
t
被定义了别名t
。在查询数据时,使用了表t
的列a
,但是没有使用别名t
,导致出现异常。
星号
select 查询中,星号可以代替表达式使用。详情请参见select。
表达式
表达式是函数、标识符、字符、使用运算符的语句、括号中的表达式、子查询或星号。它也可以包含别名。
表达式列表是用逗号分隔的一个或多个表达式。
反过来,函数和运算符可以将表达式作为参数。