2020-04-08 14:22:25 +00:00
---
machine_translated: true
2020-05-15 04:34:54 +00:00
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
2020-04-08 14:22:25 +00:00
toc_priority: 31
toc_title: "\u8BED\u6CD5"
---
# 语法 {#syntax}
系统中有两种类型的解析器: 完整SQL解析器( 递归下降解析器) 和数据格式解析器( 快速流解析器) 。
在所有情况下,除了 `INSERT` 查询时, 只使用完整的SQL解析器。
2020-05-15 04:34:54 +00:00
该 `INSERT` 查询使用两个解析器:
2020-04-08 14:22:25 +00:00
``` sql
INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def')
```
该 `INSERT INTO t VALUES` 片段由完整的解析器解析,并且数据 `(1, 'Hello, world'), (2, 'abc'), (3, 'def')` 由快速流解析器解析。 您也可以通过使用 [input\_format\_values\_interpret\_expressions ](../operations/settings/settings.md#settings-input_format_values_interpret_expressions ) 设置。 当 `input_format_values_interpret_expressions = 1` , ClickHouse首先尝试使用fast stream解析器解析值。 如果失败, ClickHouse将尝试对数据使用完整的解析器, 将其视为SQL [表达式 ](#syntax-expressions ).
数据可以有任何格式。 当接收到查询时,服务器计算不超过 [max\_query\_size ](../operations/settings/settings.md#settings-max_query_size ) RAM中请求的字节( 默认为1MB) , 其余的是流解析。
2020-05-15 04:34:54 +00:00
它允许避免与大的问题 `INSERT` 查询。
2020-04-08 14:22:25 +00:00
使用时 `Values` 格式为 `INSERT` 查询,它可能看起来数据被解析相同的表达式 `SELECT` 查询,但事实并非如此。 该 `Values` 格式更为有限。
2020-05-15 04:34:54 +00:00
本文的其余部分将介绍完整的解析器。 有关格式解析器的详细信息,请参阅 [格式 ](../interfaces/formats.md ) 科。
2020-04-08 14:22:25 +00:00
## 空间 {#spaces}
语法结构之间可能有任意数量的空格符号(包括查询的开始和结束)。 空格符号包括空格、制表符、换行符、CR和换页符。
## 评论 {#comments}
2020-05-15 04:34:54 +00:00
ClickHouse支持SQL风格和C风格的注释。
SQL风格的注释以下开头 `--` 并继续到线的末尾,一个空格后 `--` 可以省略。
C型是从 `/*` 到 `*/` 并且可以是多行,也不需要空格。
2020-04-08 14:22:25 +00:00
## 关键词 {#syntax-keywords}
当关键字对应于以下关键字时,不区分大小写:
- SQL标准。 例如, `SELECT` , `select` 和 `SeLeCt` 都是有效的。
- 在一些流行的DBMS( MySQL或Postgres) 中实现。 例如, `DateTime` 是一样的 `datetime` .
数据类型名称是否区分大小写可以在 `system.data_type_families` 桌子
与标准SQL相比, 所有其他关键字( 包括函数名称) 都是 **区分大小写** .
2020-05-15 04:34:54 +00:00
不保留关键字;它们仅在相应的上下文中被视为保留关键字。 如果您使用 [标识符 ](#syntax-identifiers ) 使用与关键字相同的名称,将它们括在双引号或反引号中。 例如,查询 `SELECT "FROM" FROM table_name` 是有效的,如果表 `table_name` 具有名称的列 `"FROM"` .
2020-04-08 14:22:25 +00:00
## 标识符 {#syntax-identifiers}
标识符是:
- 集群、数据库、表、分区和列名称。
- 功能。
- 数据类型。
- [表达式别名 ](#syntax-expression_aliases ).
2020-05-15 04:34:54 +00:00
标识符可以是引号或非引号。 后者是优选的。
2020-04-08 14:22:25 +00:00
非引号标识符必须与正则表达式匹配 `^[a-zA-Z_][0-9a-zA-Z_]*$` 并且不能等于 [关键词 ](#syntax-keywords ). 例: `x, _1, X_y__Z123_.`
如果要使用与关键字相同的标识符,或者要在标识符中使用其他符号,请使用双引号或反引号对其进行引用,例如, `"id"` , `` `id` ``.
## 文字数 {#literals}
2020-05-15 04:34:54 +00:00
有数字,字符串,复合和 `NULL` 文字。
2020-04-08 14:22:25 +00:00
### 数字 {#numeric}
2020-05-15 04:34:54 +00:00
数值文字尝试进行分析:
2020-04-08 14:22:25 +00:00
2020-05-15 04:34:54 +00:00
- 首先, 作为一个64位有符号的数字, 使用 [strtoull ](https://en.cppreference.com/w/cpp/string/byte/strtoul ) 功能。
2020-04-08 14:22:25 +00:00
- 如果不成功, 作为64位无符号数, 使用 [strtoll ](https://en.cppreference.com/w/cpp/string/byte/strtol ) 功能。
- 如果不成功,作为一个浮点数使用 [strtod ](https://en.cppreference.com/w/cpp/string/byte/strtof ) 功能。
- 否则,将返回错误。
2020-05-15 04:34:54 +00:00
文本值具有该值适合的最小类型。
2020-04-30 18:19:18 +00:00
例如, 1被解析为 `UInt8` , 但256被解析为 `UInt16` . 有关详细信息,请参阅 [数据类型 ](../sql-reference/data-types/index.md ).
2020-04-08 14:22:25 +00:00
例: `1` , `18446744073709551615` , `0xDEADBEEF` , `01` , `0.1` , `1e100` , `-1e-100` , `inf` , `nan` .
### 字符串 {#syntax-string-literal}
2020-05-15 04:34:54 +00:00
仅支持单引号中的字符串文字。 封闭的字符可以反斜杠转义。 以下转义序列具有相应的特殊值: `\b` , `\f` , `\r` , `\n` , `\t` , `\0` , `\a` , `\v` , `\xHH` . 在所有其他情况下,转义序列的格式为 `\c` ,哪里 `c` 是任何字符,被转换为 `c` . 这意味着你可以使用序列 `\'` 和`\\`. 该值将具有 [字符串 ](../sql-reference/data-types/string.md ) 类型。
2020-04-08 14:22:25 +00:00
2020-05-15 04:34:54 +00:00
在字符串文字中,你至少需要转义 `'` 和 `\` . 单引号可以用单引号,文字转义 `'It\'s'` 和 `'It''s'` 是平等的。
2020-04-08 14:22:25 +00:00
### 化合物 {#compound}
2020-05-15 04:34:54 +00:00
数组使用方括号构造 `[1, 2, 3]` . Nuples用圆括号构造 `(1, 'Hello, world!', 2)` .
从技术上讲,这些不是文字,而是分别具有数组创建运算符和元组创建运算符的表达式。
2020-04-08 14:22:25 +00:00
数组必须至少包含一个项目,元组必须至少包含两个项目。
2020-05-15 04:34:54 +00:00
有一个单独的情况下,当元组出现在 `IN` a条款 `SELECT` 查询。 查询结果可以包含元组,但元组不能保存到数据库(除了具有以下内容的表 [记忆 ](../engines/table-engines/special/memory.md ) 发动机)。
2020-04-08 14:22:25 +00:00
### NULL {#null-literal}
指示该值丢失。
2020-04-30 18:19:18 +00:00
为了存储 `NULL` 在表字段中,它必须是 [可为空 ](../sql-reference/data-types/nullable.md ) 类型。
2020-04-08 14:22:25 +00:00
根据数据格式(输入或输出), `NULL` 可能有不同的表示。 有关详细信息,请参阅以下文档 [数据格式 ](../interfaces/formats.md#formats ).
2020-05-15 04:34:54 +00:00
处理有许多细微差别 `NULL` . 例如,如果比较操作的至少一个参数是 `NULL` ,此操作的结果也是 `NULL` . 对于乘法,加法和其他操作也是如此。 有关详细信息,请阅读每个操作的文档。
2020-04-08 14:22:25 +00:00
2020-05-15 04:34:54 +00:00
在查询中,您可以检查 `NULL` 使用 [IS NULL ](operators/index.md#operator-is-null ) 和 [IS NOT NULL ](operators/index.md ) 运算符及相关功能 `isNull` 和 `isNotNull` .
2020-04-08 14:22:25 +00:00
## 功能 {#functions}
2020-05-15 04:34:54 +00:00
函数调用像一个标识符一样写入,并在圆括号中包含一个参数列表(可能是空的)。 与标准SQL相比, 括号是必需的, 即使是空的参数列表。 示例: `now()` .
2020-04-08 14:22:25 +00:00
有常规函数和聚合函数(请参阅部分 “Aggregate functions”). 某些聚合函数可以包含括号中的两个参数列表。 示例: `quantile (0.9) (x)` . 这些聚合函数被调用 “parametric” 函数,并在第一个列表中的参数被调用 “parameters”. 不带参数的聚合函数的语法与常规函数的语法相同。
## 运营商 {#operators}
在查询解析过程中,运算符会转换为相应的函数,同时考虑它们的优先级和关联性。
例如,表达式 `1 + 2 * 3 + 4` 转化为 `plus(plus(1, multiply(2, 3)), 4)` .
## 数据类型和数据库表引擎 {#data_types-and-database-table-engines}
2020-05-15 04:34:54 +00:00
数据类型和表引擎 `CREATE` 查询的编写方式与标识符或函数相同。 换句话说,它们可能包含也可能不包含括号中的参数列表。 有关详细信息,请参阅部分 “Data types,” “Table engines,” 和 “CREATE”.
2020-04-08 14:22:25 +00:00
## 表达式别名 {#syntax-expression_aliases}
别名是查询中表达式的用户定义名称。
``` sql
expr AS alias
```
- `AS` — The keyword for defining aliases. You can define the alias for a table name or a column name in a `SELECT` 子句不使用 `AS` 关键字。
For example, `SELECT table_name_alias.column_name FROM table_name table_name_alias` .
In the [CAST ](sql_reference/functions/type_conversion_functions.md#type_conversion_function-cast ) function, the `AS` keyword has another meaning. See the description of the function.
- `expr` — Any expression supported by ClickHouse.
For example, `SELECT column_name * 2 AS double FROM some_table` .
- `alias` — Name for `expr` . 别名应符合 [标识符 ](#syntax-identifiers ) 语法
For example, `SELECT "table t".column_name FROM table_name AS "table t"` .
### 使用注意事项 {#notes-on-usage}
别名对于查询或子查询是全局的,您可以在查询的任何部分中为任何表达式定义别名。 例如, `SELECT (1 AS n) + 2, n` .
别名在子查询和子查询之间不可见。 例如,在执行查询时 `SELECT (SELECT sum(b.a) + num FROM b) - a.a AS num FROM a` ClickHouse生成异常 `Unknown identifier: num` .
如果为结果列定义了别名 `SELECT` 子查询的子句,这些列在外部查询中可见。 例如, `SELECT n + m FROM (SELECT 1 AS n, 2 AS m)` .
小心使用与列或表名相同的别名。 让我们考虑以下示例:
``` sql
CREATE TABLE t
(
a Int,
b Int
)
ENGINE = TinyLog()
```
``` sql
SELECT
argMax(a, b),
sum(b) AS b
FROM t
```
``` text
Received exception from server (version 18.14.17):
Code: 184. DB::Exception: Received from localhost:9000, 127.0.0.1. DB::Exception: Aggregate function sum(b) is found inside another aggregate function in query.
```
在这个例子中,我们声明表 `t` 带柱 `b` . 然后,在选择数据时,我们定义了 `sum(b) AS b` 别名 由于别名是全局的, ClickHouse替换了文字 `b` 在表达式中 `argMax(a, b)` 用表达式 `sum(b)` . 这种替换导致异常。
## 星号 {#asterisk}
在一个 `SELECT` 查询中,星号可以替换表达式。 有关详细信息,请参阅部分 “SELECT”.
## 表达式 {#syntax-expressions}
表达式是函数、标识符、文字、运算符的应用程序、括号中的表达式、子查询或星号。 它还可以包含别名。
表达式列表是一个或多个用逗号分隔的表达式。
函数和运算符,反过来,可以有表达式作为参数。
2020-05-15 04:34:54 +00:00
[原始文章 ](https://clickhouse.tech/docs/en/sql_reference/syntax/ ) <!--hide-->