BigQuery 语句由一系列标记组成。标记包括标识符、带英文引号的标识符、字面量、关键字、运算符和特殊字符。您可以使用空格符(如空格、退格、制表符、换行符)或注释来分隔这些标记。
标识符
标识符是指与列、表和其他数据库对象关联的名称。标识符可以不带英文引号,也可以带英文引号。
- 标识符可用于返回
STRUCT
的路径表达式。 - 一些标识符区分大小写,一些则不区分大小写。如需了解详情,请参阅区分大小写。
- 不带英文引号的标识符必须以字母或下划线字符开头。后续字符可以是字母、数字或下划线。
- 带英文引号的标识符必须用反引号 (`) 字符括起来。
- 在
FROM
和TABLE
子句中引用时,表名称标识符具有支持短划线 (-) 的其他语法。
示例
以下是有效的标识符:
Customers5
`5Customers`
dataField
_dataField1
ADGROUP
`tableName~`
`GROUP`
以下路径表达式包含有效的标识符:
foo.`GROUP`
foo.GROUP
foo().dataField
list[OFFSET(3)].dataField
list[ORDINAL(3)].dataField
@parameter.dataField
以下是无效的标识符:
5Customers
_dataField!
GROUP
5Customers
以数字开头,而不是以字母或下划线开头。_dataField!
包含特殊字符“!”,这个特殊字符不是字母、数字或下划线。
GROUP
是一个预留关键字,因此未用反引号括起时不能用作标识符。
您不需要用英文反引号将包含短划线的表名括起来。这些等价于:
SELECT * FROM data-customers-287.mydatabase.mytable
SELECT * FROM `data-customers-287`.mydatabase.mytable
字面量
字面量代表内置数据类型的常量值。某些数据类型可以使用字面量表示,但并非全部数据类型都是如此。
字符串和字节字面量
字符串和字节字面量都必须用英文单引号 ('
)、英文双引号 ("
) 或英文三引号(可以是三个英文单引号 ('''
) 或三个英文双引号 ("""
))括起来。
带英文引号的字面量:
字面量 | 示例 | 说明 |
---|---|---|
带英文引号的字符串 |
|
用英文单引号 (' ) 括起的字符串可以包含未转义的英文双引号 (" ),反之亦然。反斜杠 ( \ ) 可引入转义序列。请参阅下面的“转义序列”表。带英文引号的字符串不能包含换行符,即使前面加了反斜杠 ( \ ) 也不允许。 |
带英文三引号的字符串 |
|
您可以嵌入换行符和英文引号,而无需转义(请参见第四个示例)。 反斜杠 ( \ ) 可引入转义序列。请参阅下面的“转义序列”表。不允许在行尾处使用未转义的尾随反斜杠 ( \ )。行中与起始英文引号匹配的三个未转义英文引号表示此字符串结束。 |
原始字符串 |
|
具有原始字符串字面量前缀(r 或 R )且带英文引号或三引号的字面量会被解释为原始/正则表达式字符串。反斜杠字符 ( \ ) 不充当转义字符。如果字符串字面量内出现反斜杠后跟另一个字符的形式,则这两个字符都将保留。原始字符串不能以奇数个反斜杠结束。 原始字符串对于构造正则表达式很有用。 |
在带英文引号或三引号的字符串中,前缀字符(r
、R
、b
、B)
)是可选项,分别指示该字符串是原始/正则表达式字符串或字节序列。例如,b'abc'
和 b'''abc'''
都会被解释为字节类型。前缀字符不区分大小写。
带前缀且带英文引号的字面量:
字面量 | 示例 | 说明 |
---|---|---|
字节 |
|
具有字节字面量前缀(b 或 B )且带英文引号或三引号的字面量会被解释为字节。 |
原始字节 |
|
r 和 b 前缀可按任意顺序组合。例如,rb'abc*' 等同于 br'abc*' 。 |
下表列出了可在字符串和字节字面量中代表非字母数字字符的所有有效转义序列。 此表未列出的任何序列都会引发错误。
转义序列 | 说明 |
---|---|
\a |
响铃 |
\b |
退格符 |
\f |
换页符 |
\n |
换行符 |
\r |
回车符 |
\t |
制表符 |
\v |
垂直制表符 |
\\ |
反斜杠 (\ ) |
\? |
英文问号 (? ) |
\" |
英文双引号 (" ) |
\' |
英文单引号 (' ) |
\` |
英文反引号 (` ) |
\ooo |
由 3 位数字(介于 0 到 7 范围内)组成的八进制转义字符。解码为单个 Unicode 字符(字符串字面量形式)或字节(字节字面量形式)。 |
\xhh 或 \Xhh |
由 2 个十六进制数字(0-9、A-F 或 a-f)组成的十六进制转义字符。解码为单个 Unicode 字符(字符串字面量形式)或字节(字节字面量形式)。示例:
|
\uhhhh |
Unicode 转义字符,包含小写“u”和 4 个十六进制数字。仅在字符串字面量或标识符中有效。 请注意,系统不允许使用 D800-DFFF 范围内的值,因为这些是代理 Unicode 值。 |
\Uhhhhhhhh |
Unicode 转义字符,包含大写“U”和 8 个十六进制数字。仅在字符串字面量或标识符中有效。 系统不允许使用 D800-DFFF 范围内的值,因为这些值是代理 Unicode 值。此外,不允许大于 10FFFF 的值。 |
整数字面量
整数字面量可以是一系列十进制数字(0 到 9),也可以是一个前缀为“0x
”或“0X
”的十六进制值。整数可以使用“+
”或“-
”作为前缀,分别表示正值和负值。
示例:
123
0xABC
-123
整数字面量会被解释为 INT64
。
数字字面量
您可以使用 NUMERIC
关键字后接括在英文引号中的浮点值的形式,构造 NUMERIC 字面量。
示例:
SELECT NUMERIC '0';
SELECT NUMERIC '123456';
SELECT NUMERIC '-3.14';
SELECT NUMERIC '-0.54321';
SELECT NUMERIC '1.23456e05';
SELECT NUMERIC '-9.876e-3';
BIGNUMERIC 字面量
您可以使用 BIGNUMERIC
关键字后接括在英文引号中的浮点值的形式,构造 BIGNUMERIC
字面量。
示例:
SELECT BIGNUMERIC '0';
SELECT BIGNUMERIC '123456';
SELECT BIGNUMERIC '-3.14';
SELECT BIGNUMERIC '-0.54321';
SELECT BIGNUMERIC '1.23456e05';
SELECT BIGNUMERIC '-9.876e-3';
浮点数字面量
语法选项:
[+-]DIGITS.[DIGITS][e[+-]DIGITS]
[DIGITS].DIGITS[e[+-]DIGITS]
DIGITSe[+-]DIGITS
DIGITS
表示一个或多个十进制数字(0 到 9),e
表示指数标记(e 或 E)。
示例:
123.456e-67
.1E4
58.
4e2
系统会假定包含小数点或指数标记的数值字面量属于双精度类型。
如果值在有效的浮点数范围内,则可以将浮点数字面量的类型隐式强制转换为浮点数类型。
NaN 或无穷大没有字面量表示,但以下不区分大小写的字符串可显式强制转换为浮点数:
- “NaN”
- “inf”或“+inf”
- “-inf”
数组字面量
数组字面量是用方括号括起来且以英文逗号分隔的元素列表。ARRAY
关键字是可选的,显式元素类型 T 也是可选的。
示例:
[1, 2, 3]
['x', 'y', 'xy']
ARRAY[1, 2, 3]
ARRAY<string>['x', 'y', 'xy']
ARRAY<int64>[]
结构体字面量
语法:
(elem[, elem...])
其中,elem
是结构体中的一个元素。elem
必须是字面量数据类型,而不是表达式或列名称。
输出类型是匿名 struct 类型(struct 不是命名类型),其匿名字段的类型与输入表达式的类型匹配。
示例 | 输出类型 |
---|---|
(1, 2, 3) |
STRUCT<int64,int64,int64> |
(1, 'abc') |
STRUCT<int64,string> |
日期字面量
语法:
DATE 'YYYY-M[M]-D[D]'
日期字面量包含 DATE
关键字,后跟遵循规范日期格式的字符串字面量(用英文单引号括起)。日期字面量支持 1 至 9999(含)的年份范围。此范围之外的日期无效。
例如,以下日期字面量代表 2014 年 9 月 27 日:
DATE '2014-09-27'
在应使用“日期”类型表达式的情况下使用时,规范日期格式中的字符串字面量也会隐式强制转换为“日期”类型。例如,在以下查询中:
SELECT * FROM foo WHERE date_col = "2014-09-27"
字符串字面量 "2014-09-27"
将被强制转换为日期字面量。
时间字面量
语法:
TIME '[H]H:[M]M:[S]S[.DDDDDD]]'
时间字面量包含 TIME
关键字和一个遵循规范时间格式的字符串字面量(用英文单引号括起)。
例如,以下时间代表中午 12:30:
TIME '12:30:00.45'
日期时间字面量
语法:
DATETIME 'YYYY-[M]M-[D]D [[H]H:[M]M:[S]S[.DDDDDD]]'
日期时间字面量包含 DATETIME
关键字和一个遵循规范日期时间格式的字符串字面量(用英文单引号括起)。
例如,以下日期时间代表 2014 年 9 月 27 日中午 12:30:
DATETIME '2014-09-27 12:30:00.45'
日期时间字面量支持 1 至 9999(含边界值)的年份范围。 超出此范围的日期时间无效。
在应使用日期时间表达式的情况下使用时,采用规范日期时间格式的字符串字面量会隐式强制转换为日期时间字面量。
例如:
SELECT * FROM foo
WHERE datetime_col = "2014-09-27 12:30:00.45"
在上面的查询中,字符串字面量 "2014-09-27 12:30:00.45"
被强制转换为日期时间字面量。
日期时间字面量还可以包含可选的字符 T
或 t
。这是一个时间标志,用作日期和时间之间的分隔符。如果您使用此字符,则不能在其前面或后面添加空格。以下日期时间字面量是有效的:
DATETIME '2014-09-27T12:30:00.45'
DATETIME '2014-09-27t12:30:00.45'
时间戳字面量
语法:
TIMESTAMP 'YYYY-[M]M-[D]D [[H]H:[M]M:[S]S[.DDDDDD] [timezone]]'
时间戳字面量包含 TIMESTAMP
关键字和一个字符串字面量,该字符串字面量遵循规范时间戳格式并用英文单引号括起。
时间戳字面量支持 1 至 9999(含)的年份范围。 此范围之外的时间戳是无效的。
时间戳字面量可以包含一个数字后缀来指示时区:
TIMESTAMP '2014-09-27 12:30:00.45-08'
如果此后缀不存在,则将使用默认时区世界协调时间 (UTC)。
例如,以下时间戳表示世界协调时间 (UTC) 时区 2014 年 9 月 27 日中午 12:30:
TIMESTAMP '2014-09-27 12:30:00.45'
如需详细了解时区,请参阅时区。
在应使用时间戳表达式的位置使用规范时间戳格式的字符串字面量(包括具有时区名称的那些字面量)时,该字符串字面量会隐式强制转换为时间戳字面量。例如,在以下查询中,字符串字面量 "2014-09-27 12:30:00.45 America/Los_Angeles"
会被强制转换为时间戳字面量。
SELECT * FROM foo
WHERE timestamp_col = "2014-09-27 12:30:00.45 America/Los_Angeles"
时间戳字面量可以包含以下可选的字符:
T
或t
:时间标志。用作日期和时间之间的分隔符。Z
或z
:默认时区标志。这两个字符不能与[timezone]
搭配使用。
如果您使用这些字符之一,则不能在其前面或后面添加空格。以下日期时间字面量是有效的:
TIMESTAMP '2017-01-18T12:34:56.123456Z'
TIMESTAMP '2017-01-18t12:34:56.123456'
TIMESTAMP '2017-01-18 12:34:56.123456z'
TIMESTAMP '2017-01-18 12:34:56.123456Z'
时区
由于时间戳字面量必须映射到特定时间点,因此需要时区来正确解释字面量。如果未在字面量本身内指定时区,则 BigQuery 将使用 BigQuery 实现设置的默认时区值。
BigQuery 使用以下规范格式的字符串表示时区,该格式表示相对于协调世界时 (UTC) 的偏移量。
格式:
(+|-)H[H][:M[M]]
示例:
'-08:00'
'-8:15'
'+3:00'
'+07:30'
'-7'
也可以使用 tz 数据库中的字符串时区名称来表示时区。请参阅维基百科上的 tz 数据库时区列表,其中提供了虽不全面但较为简单的参考信息。规范时区名称的格式为 <continent/[region/]city>
,例如 America/Los_Angeles
。
示例:
TIMESTAMP '2014-09-27 12:30:00 America/Los_Angeles'
TIMESTAMP '2014-09-27 12:30:00 America/Argentina/Buenos_Aires'
区分大小写
BigQuery 遵循以下区分大小写规则:
类别 | 是否区分大小写? | 备注 |
---|---|---|
关键字 | 否 | |
内置函数名称 | 否 | |
用户定义的函数名称 | 是 | |
表名称 | 是 | |
列名称 | 否 | |
字符串值 | 是 | |
字符串比较 | 是 | |
查询中的别名 | 否 | |
正则表达式匹配 | 请参见备注 | 默认情况下,正则表达式匹配区分大小写,除非表达式本身指定不区分大小写。 |
LIKE 匹配 |
是 |
预留关键字
关键字是 BigQuery 语言中具有特殊含义的一组标记,具有以下特征:
- 只有在使用反引号 (`) 字符括起时,关键字才能用作标识符。
- 关键字不区分大小写。
BigQuery 提供以下预留关键字。
ALL AND ANY ARRAY AS ASC ASSERT_ROWS_MODIFIED AT BETWEEN BY CASE CAST COLLATE CONTAINS CREATE CROSS CUBE CURRENT DEFAULT DEFINE DESC DISTINCT ELSE END |
ENUM ESCAPE EXCEPT EXCLUDE EXISTS EXTRACT FALSE FETCH FOLLOWING FOR FROM FULL GROUP GROUPING GROUPS HASH HAVING IF IGNORE IN INNER INTERSECT INTERVAL INTO |
IS JOIN LATERAL LEFT LIKE LIMIT LOOKUP MERGE NATURAL NEW NO NOT NULL NULLS OF ON OR ORDER OUTER OVER PARTITION PRECEDING PROTO RANGE |
RECURSIVE RESPECT RIGHT ROLLUP ROWS SELECT SET SOME STRUCT TABLESAMPLE THEN TO TREAT TRUE UNBOUNDED UNION UNNEST USING WHEN WHERE WINDOW WITH WITHIN |
终止分号
在通过应用编程接口 (API) 提交查询字符串语句时,您可以视情况使用终止分号 (;
)。
在包含多个语句的请求中,您必须使用分号分隔各个语句,但最后一个语句后的分号通常是可选的。 一些交互式工具要求语句使用终止分号。
尾随逗号
您可以视情况选择在 SELECT
语句的列列表末尾使用尾随英文逗号 (,
)。以编程方式创建列列表时,您可能会使用尾随英文逗号。
示例
SELECT name, release_date, FROM Books
查询参数
您可以使用查询参数替换任意表达式。 但查询参数不能用于替换标识符、列名称、表名称或查询本身的其他部分。查询参数是在查询语句之外定义的。
客户端 API 允许将参数名称与值绑定;查询引擎会在执行时将参数替换成绑定的值。
查询参数不能在以下语句的 SQL 正文中使用:CREATE FUNCTION
、CREATE VIEW
、CREATE MATERIALIZED VIEW
和 CREATE PROCEDURE
。
命名的查询参数
语法:
@parameter_name
命名的查询参数使用以 @
字符开头的标识符来表示。命名的查询参数不能与位置查询参数一起使用。
示例:
此示例会返回 LastName
等于命名的查询参数 myparam
的值的所有行。
SELECT * FROM Roster WHERE LastName = @myparam
位置查询参数
位置查询参数使用 ?
字符表示。位置参数按照其传入顺序进行评估。位置查询参数不能与命名的查询参数一起使用。
示例:
此查询会返回 LastName
和 FirstName
等于传入此查询的值的所有行。传入这些值所按照的顺序很重要。如果先传入姓氏,然后再传入名字,则不会返回预期结果。
SELECT * FROM Roster WHERE FirstName = ? and LastName = ?
注释
注释是会被解析器忽略的字符序列。 BigQuery 支持以下类型的注释。
单行注释
如果您希望注释单独显示在一行上,请使用单行注释。
示例
# this is a single-line comment
SELECT book FROM library;
-- this is a single-line comment
SELECT book FROM library;
/* this is a single-line comment */
SELECT book FROM library;
SELECT book FROM library
/* this is a single-line comment */
WHERE book = "Ulysses";
内嵌注释
如果您希望注释与语句显示在同一行上,请使用内嵌注释。前缀为 #
或 --
的注释必须位于语句的右侧。
示例
SELECT book FROM library; # this is an inline comment
SELECT book FROM library; -- this is an inline comment
SELECT book FROM library; /* this is an inline comment */
SELECT book FROM library /* this is an inline comment */ WHERE book = "Ulysses";
多行注释
如果您需要添加跨越多行的注释,请使用多行注释。 系统不支持嵌套的多行注释。
示例
SELECT book FROM library
/*
This is a multiline comment
on multiple lines
*/
WHERE book = "Ulysses";
SELECT book FROM library
/* this is a multiline comment
on two lines */
WHERE book = "Ulysses";