标准 SQL 函数和运算符

本页面介绍 BigQuery 表达式,包括函数和运算符。

函数调用规则

除非函数说明中另有明确规定,否则以下规则适用于所有函数:

  • 对于接受数字类型的函数,如果一个操作数是浮点型,而另一个操作数是数字型,则必须先将这两个操作数转换为 FLOAT64 后才能开始计算此函数。
  • 如果一个操作数是 NULL,则结果为 NULL,IS 运算符除外。

  • 对于区分时区的函数(如函数说明中所述),如果未指定时区,则使用默认时区“世界协调时间 (UTC)”。

SAFE. 前缀

语法:

SAFE.function_name()

说明

如果一个函数以 SAFE. 前缀开头,则会返回 NULL 而非错误。SAFE. 前缀仅会防止带有前缀的函数本身返回错误,不能防止在计算参数表达式时出现错误。SAFE. 前缀仅会防止因函数输入值而发生的错误,例如“值超出范围”错误,但内部错误或系统错误等其他错误仍可能会发生。如果函数未返回错误,SAFE. 对输出无任何影响。如果函数决不会返回错误,像 RAND 函数就是如此,那么 SAFE. 也没有任何影响。

+=运算符不支持 SAFE. 前缀。为防止除法运算出错,请使用 SAFE_DIVIDE。某些运算符(例如 INARRAYUNNEST)与函数类似,但不支持 SAFE. 前缀。CASTEXTRACT 函数也不支持 SAFE. 前缀。为防止类型转换出错,请使用 SAFE_CAST

示例

在以下示例中,SUBSTR 函数的第一处使用正常应该返回错误,因为该函数不支持值为负的长度参数。但是,该函数带有 SAFE. 前缀,因此返回 NULLSUBSTR 函数的第二处使用提供了预期输出:SAFE. 前缀无任何影响。

SELECT SAFE.SUBSTR('foo', 0, -2) AS safe_output UNION ALL
SELECT SAFE.SUBSTR('bar', 0, 2) AS safe_output;

+-------------+
| safe_output |
+-------------+
| NULL        |
| ba          |
+-------------+

支持的函数

BigQuery 支持对大多数可能抛出错误的标量函数使用 SAFE. 前缀,此类函数包括 STRING 函数数学函数DATE 函数DATETIME 函数TIMESTAMP 函数。BigQuery 不支持对聚合函数分析函数用户定义的函数使用 SAFE. 前缀。

调用永久性用户定义的函数 (UDF)

注意:针对永久性 UDF 的 BigQuery 支持目前处于测试版阶段。如需了解详情,请参阅产品发布阶段

创建永久性 UDF 后,您可以像调用任何其他函数一样调用该函数,并附加它所在的数据集的名称作为前缀。

语法

[`project_name`].dataset_name.function_name([parameter_value[, ...]])

如果您在一个项目中运行查询,但要调用其他项目中的 UDF,则需要带上 project_name

示例

以下示例创建名为 multiply_by_three 的 UDF,并从同一项目中调用它。

CREATE FUNCTION my_dataset.multiply_by_three(x INT64) AS (x * 3);

SELECT my_dataset.multiply_by_three(5) AS result; -- returns 15

以下示例从其他项目中调用永久性 UDF。

CREATE `other_project`.other_dataset.other_function(x INT64, y INT64)
  AS (x * y * 2);

SELECT `other_project`.other_dataset.other_function(3, 4); --returns 24

转换规则

“转换”包括但不限于类型转换 (casting) 和强制转换 (coercion)。

  • 类型转换属于显式转换,使用 CAST() 函数。
  • 强制转换属于隐式转换,BigQuery 在下述条件下会自动执行此转换。
  • 此外还存在第三种转换函数,其自带函数名称,例如 UNIX_DATE()

下表汇总了 BigQuery 数据类型所有可能的 CAST 和强制转换。“强制转换为”可应用于指定数据类型(例如列类型)的所有表达式,而且也支持对字面量和参数进行强制转换。如需了解详情,请参阅字面量强制转换参数强制转换

原类型 类型转换目标类型 强制转换目标类型
INT64 BOOL
INT64
NUMERIC
FLOAT64
STRING
FLOAT64
NUMERIC
NUMERIC INT64
NUMERIC
FLOAT64
STRING
FLOAT64
FLOAT64 INT64
NUMERIC
FLOAT64
STRING
 
BOOL BOOL
INT64
STRING
 
STRING BOOL
INT64
NUMERIC
FLOAT64
STRING
BYTES
DATE
DATETIME
TIME
TIMESTAMP
 
BYTES BYTES
STRING
 
DATE DATE
DATETIME
STRING
TIMESTAMP
 
DATETIME DATE
DATETIME
STRING
TIME
TIMESTAMP
 
TIME STRING
TIME
 
TIMESTAMP DATE
DATETIME
STRING
TIME
TIMESTAMP
 
ARRAY ARRAY  
STRUCT STRUCT  

类型转换

语法:

CAST(expr AS typename)

类型转换语法在查询中使用,用于指示表达式的结果类型应转换成其他某种类型。

示例:

CAST(x=1 AS STRING)

如果 x1,则此表达式的结果为 "true";如果为任何其他非 NULL 值,结果为 "false";如果 xNULL,则结果为 NULL

如果受支持的类型之间的类型转换未从原始值成功地映射到目标域,则会引发运行时错误。例如,如果字节序列不是有效的 UTF-8,则将 BYTES 类型转换为 STRING 类型会导致运行时错误。

在对以下类型的表达式 x 进行类型转换时,下述规则适用:

原类型 目标类型 x 进行类型转换时适用的规则
INT64 FLOAT64 返回一个接近但可能不精确的 FLOAT64 值。
INT64 BOOL 如果 x0,则返回 FALSE;否则返回 TRUE
NUMERIC 浮点 NUMERIC 类型将转换为最接近的浮点数,可能有一定的精度损失。
FLOAT64 INT64 返回最接近的 INT64 值。
中间数(例如 1.5 或 -0.5)向远离 0 的方向舍入。
FLOAT64 STRING 返回一个近似的字符串表示形式。
FLOAT64 NUMERIC 如果浮点数的小数点后的位数超过 9 位,则会向远离 0 方向按中间数舍入。对 NaN+inf-inf 进行类型转化会返回错误。对 NUMERIC 范围以外的值进行类型转换会返回溢出错误。
BOOL INT64 如果 xTRUE,则返回 1;否则返回 0
BOOL STRING 如果 xTRUE,则返回 "true",否则返回 "false"
STRING FLOAT64 以 FLOAT64 值的形式返回 x,将其解释为具有与有效的 FLOAT64 字面量相同的形式。
也支持从 "inf""+inf""-inf""nan" 进行类型转换。
转换不区分大小写。
STRING NUMERIC STRING 中包含的数字字面量不得超出 NUMERIC 类型的最大精度或范围,否则将发生错误。如果小数点后的位数超过 9 位,则生成的 NUMERIC 值会向远离 0 方向舍入,从而在小数点后保留 9 位数。
STRING BOOL 如果 x"true",则返回 TRUE;如果 xFALSE,则返回 "false"
x 的所有其他值均无效且引发错误,而不会转换为 BOOL。
转换为 BOOL 时,STRING 不区分大小写。
STRING BYTES STRING 通过 UTF-8 编码转换为 BYTES。例如,在转换为 BYTES 时,字符串“©”会转为一个包含十六进制值 C2 和 A9 的 2 字节序列。
BYTES STRING 返回解释为 UTF-8 STRING 的 x
例如,在转换为 STRING 时,BYTES 字面量 b'\xc2\xa9' 会解释为 UTF-8 并且转为 Unicode 字符“©”。
如果 x 不是有效的 UTF-8,则引发错误。
ARRAY ARRAY 两者必须是完全相同的 ARRAY 类型。
STRUCT STRUCT 仅在满足以下条件时可用:
  1. 这两个 STRUCT 的字段数量相同。
  2. 原始 STRUCT 字段类型可显式转换为相应的目标 STRUCT 字段类型(由字段顺序定义,而不是由字段名称定义)。

安全类型转换

在使用 CAST 时,如果 BigQuery 无法执行类型转换,查询就会失败。例如,以下查询会生成错误:

SELECT CAST("apple" AS INT64) AS not_a_number;

若要保护您的查询,避免这些类型的错误,您可以使用 SAFE_CASTSAFE_CAST 基本等同于 CAST,唯一的差别就在于前者返回 NULL,而非引发错误。

SELECT SAFE_CAST("apple" AS INT64) AS not_a_number;

+--------------+
| not_a_number |
+--------------+
| NULL         |
+--------------+

如果将字节转换为字符串,您还可以使用 SAFE_CONVERT_BYTES_TO_STRING 函数。任何无效的 UTF-8 字符都会替换为 Unicode 替换字符 U+FFFD。如需了解详情,请参阅 SAFE_CONVERT_BYTES_TO_STRING

将十六进制字符串转换为整数

如果您使用十六进制字符串 (0x123),可以将这些字符串的类型转换为整数:

SELECT '0x123' as hex_value, CAST('0x123' as INT64) as hex_to_int;

+-----------+------------+
| hex_value | hex_to_int |
+-----------+------------+
| 0x123     | 291        |
+-----------+------------+

SELECT '-0x123' as hex_value, CAST('-0x123' as INT64) as hex_to_int;

+-----------+------------+
| hex_value | hex_to_int |
+-----------+------------+
| -0x123    | -291       |
+-----------+------------+

转换日期类型

BigQuery 支持在日期类型与字符串之间相互转换,如下所示:

CAST(date_expression AS STRING)
CAST(string_expression AS DATE)

日期类型转换为字符串与时区无关,并采用 YYYY-MM-DD 形式。字符串转换为日期时,字符串必须遵循所支持的日期字面量格式,但与时区无关。如果字符串表达式无效或其表示的日期超出了所支持的最小/最大范围,则出现错误。

转换时间戳类型

BigQuery 支持在时间戳类型与字符串之间相互转换,如下所示:

CAST(timestamp_expression AS STRING)
CAST(string_expression AS TIMESTAMP)

时间戳类型转换为字符串时,使用默认时区世界协调时间 (UTC) 解释时间戳。所生成的亚秒位数取决于亚秒部分中尾随零的数量:CAST 函数将截取 0、3 或 6 位数。

字符串转换为时间戳时,string_expression 必须遵循所支持的时间戳字面量格式,否则将出现运行时错误。string_expression 可能自带一个 time_zone,具体请参阅时区。如果 string_expression 中存在时区,则转换时使用该时区,否则使用默认时区世界协调时间 (UTC)。如果字符串少于 6 位数,则将其隐式加宽。

如果 string_expression 无效,其亚秒位数超过 6 位数(即精度高于微秒),或者所表示的时间超出了支持的时间戳范围,则会引发错误。

在日期和时间戳类型之间转换

BigQuery 支持在日期与时间戳类型之间相互转换,如下所示:

CAST(date_expression AS TIMESTAMP)
CAST(timestamp_expression AS DATE)

如果从日期转换为时间戳,则从默认时区世界协调时间 (UTC) 的午夜(一天之始)起解释 date_expression。如果从时间戳转换为日期,则自默认时区起实际截断时间戳。

强制转换

如果需要匹配函数签名,BigQuery 会将表达式的结果转换成其他类型。例如,如果函数 func() 定义为获取 INT64 类型的单个参数,并使用一个表达式作为结果类型为 FLOAT64 的参数,则在该表达式的结果转换为 INT64 类型后,才开始计算 func()。

字面量强制转换

BigQuery 支持以下字面量强制转换:

输入数据类型 结果数据类型 备注
STRING 字面量 DATE
TIMESTAMP

在实际字面量类型不同于相关函数预期的类型时,就需要字面量强制转换。举例来说,如果函数 func() 获取一个 DATE 参数,则表达式 func("2014-09-27") 有效,因为 STRING 字面量 "2014-09-27" 强制转换为 DATE。

字面量转换会在分析时进行评估,如果输入子面子无法成功转换为目标类型,则引发错误。

注意:字符串字面量不会强制转换为数字类型。

参数强制转换

BigQuery 支持以下参数强制转换:

输入数据类型 结果数据类型
STRING 参数

如果参数值无法成功强制转换为目标类型,则引发错误。

其他转换函数

BigQuery 还提供以下转换函数:

聚合函数

聚合函数是对一组值执行计算的函数。例如,COUNT、MIN 和 MAX 都是聚合函数。

SELECT COUNT(*) as total_count, COUNT(fruit) as non_null_count,
       MIN(fruit) as min, MAX(fruit) as max
FROM UNNEST([NULL, "apple", "pear", "orange"]) as fruit;
+-------------+----------------+-------+------+
| total_count | non_null_count | min   | max  |
+-------------+----------------+-------+------+
| 4           | 3              | apple | pear |
+-------------+----------------+-------+------+

以下部分介绍了 BigQuery 支持的聚合函数。

ANY_VALUE

ANY_VALUE(expression)  [OVER (...)]

说明

返回输入的任何值;如果不存在任何输入行,则返回 NULL。返回的值是不确定的,这意味着您在每次使用此函数时都可能得到不同的结果。

支持的参数类型

任意

可选子句

OVER:指定一个窗口。请参见分析函数

返回的数据类型

与输入数据类型相匹配。

示例

SELECT ANY_VALUE(fruit) as any_value
FROM UNNEST(["apple", "banana", "pear"]) as fruit;

+-----------+
| any_value |
+-----------+
| apple     |
+-----------+

SELECT
  fruit,
  ANY_VALUE(fruit) OVER (ORDER BY LENGTH(fruit) ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS any_value
FROM UNNEST(["apple", "banana", "pear"]) as fruit;

+--------+-----------+
| fruit  | any_value |
+--------+-----------+
| pear   | pear      |
| apple  | pear      |
| banana | apple     |
+--------+-----------+

ARRAY_AGG

ARRAY_AGG([DISTINCT] expression [{IGNORE|RESPECT} NULLS]
          [ORDER BY key [{ASC|DESC}] [, ... ]]  [LIMIT n])
[OVER (...)]

说明

返回 ARRAY 类型的 expression 值。

支持的参数类型

除 ARRAY 以外的所有数据类型。

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数。此子句目前与 ARRAY_AGG() 内的所有其他子句均不兼容。

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

  3. IGNORE NULLSRESPECT NULLS:如果指定了 IGNORE NULLS,则从结果中排除 NULL 值。如果指定了 RESPECT NULLS 或者未指定任何一个子句,结果中会包含 NULL 值(但如果最终查询结果中的数组包含 NULL 元素,则会报错)。

  4. ORDER BY:指定值的顺序。

    • 对于每个排序键,默认排序方向均为 ASC
    • NULL:在 ORDER BY 子句的上下文中,NULL 是可能的最小值;也就是说,NULL 在 ASC 排序方向中出现在最前位置,在 DESC 排序方向中出现在最后位置。
    • 浮点数据类型:如需了解排序和分组,请参阅浮点语义
    • 如果同时还指定了 DISTINCT,排序键必须与 expression 相同。
    • 如果未指定 ORDER BY,输出数组中的元素顺序是不确定的,这意味着您在每次使用此函数时可能得到不同的结果。
  5. LIMIT:指定结果中 expression 输入的最大数量。上限 n 必须是 INT64 常量。

返回的数据类型

ARRAY

如果不存在输入行,则此函数返回 NULL

示例

SELECT FORMAT("%T", ARRAY_AGG(x)) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;

+-------------------------+
| array_agg               |
+-------------------------+
| [2, 1, -2, 3, -2, 1, 2] |
+-------------------------+
SELECT FORMAT("%T", ARRAY_AGG(DISTINCT x)) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;

+---------------+
| array_agg     |
+---------------+
| [2, 1, -2, 3] |
+---------------+
SELECT FORMAT("%T", ARRAY_AGG(x IGNORE NULLS)) AS array_agg
FROM UNNEST([NULL, 1, -2, 3, -2, 1, NULL]) AS x;

+-------------------+
| array_agg         |
+-------------------+
| [1, -2, 3, -2, 1] |
+-------------------+
SELECT FORMAT("%T", ARRAY_AGG(x ORDER BY ABS(x))) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;
+-------------------------+
| array_agg               |
+-------------------------+
| [1, 1, 2, -2, -2, 2, 3] |
+-------------------------+
SELECT FORMAT("%T", ARRAY_AGG(x LIMIT 5)) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;

+-------------------+
| array_agg         |
+-------------------+
| [2, 1, -2, 3, -2] |
+-------------------+
SELECT FORMAT("%T", ARRAY_AGG(DISTINCT x IGNORE NULLS ORDER BY x LIMIT 2)) AS array_agg
FROM UNNEST([NULL, 1, -2, 3, -2, 1, NULL]) AS x;

+-----------+
| array_agg |
+-----------+
| [-2, 1]   |
+-----------+
SELECT
  x,
  FORMAT("%T", ARRAY_AGG(x) OVER (ORDER BY ABS(x))) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;

+----+-------------------------+
| x  | array_agg               |
+----+-------------------------+
| 1  | [1, 1]                  |
| 1  | [1, 1]                  |
| 2  | [1, 1, 2, -2, -2, 2]    |
| -2 | [1, 1, 2, -2, -2, 2]    |
| -2 | [1, 1, 2, -2, -2, 2]    |
| 2  | [1, 1, 2, -2, -2, 2]    |
| 3  | [1, 1, 2, -2, -2, 2, 3] |
+----+-------------------------+

ARRAY_CONCAT_AGG

ARRAY_CONCAT_AGG(expression  [ORDER BY key [{ASC|DESC}] [, ... ]]  [LIMIT n])

说明

连接类型为 ARRAY 的 expression 中的元素,返回一个 ARRAY 作为结果。此函数会忽略 NULL 输入数组,但会考虑非 NULL 输入数组中的 NULL 元素(但如果最终查询结果中的数字包含 NULL 元素,则会引发错误)。

支持的参数类型

ARRAY

可选子句

子句按照以下顺序应用

  1. ORDER BY:指定值的顺序。

    • 对于每个排序键,默认排序方向均为 ASC
    • 不支持数组排序,因此排序键必须与 expression 相同。
    • NULL:在 ORDER BY 子句的上下文中,NULL 是可能的最小值;也就是说,NULL 在 ASC 排序方向中出现在最前位置,在 DESC 排序方向中出现在最后位置。
    • 浮点数据类型:如需了解排序和分组,请参阅浮点语义
    • 如果未指定 ORDER BY,输出数组中的元素顺序是不确定的,这意味着您在每次使用此函数时可能得到不同的结果。
  2. LIMIT:指定结果中 expression 输入的最大数量。此上限适用于输入数组数量,而非数组中的元素数量。空数组计为 1。NULL 数组不计数。上限 n 必须是 INT64 常量。

返回的数据类型

ARRAY

如果不存在任何输入行或所有行的 expression 计算结果均为 NULL,则返回 NULL

示例

SELECT FORMAT("%T", ARRAY_CONCAT_AGG(x)) AS array_concat_agg FROM (
  SELECT [NULL, 1, 2, 3, 4] AS x
  UNION ALL SELECT NULL
  UNION ALL SELECT [5, 6]
  UNION ALL SELECT [7, 8, 9]
);

+-----------------------------------+
| array_concat_agg                  |
+-----------------------------------+
| [NULL, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
+-----------------------------------+

SELECT FORMAT("%T", ARRAY_CONCAT_AGG(x ORDER BY ARRAY_LENGTH(x))) AS array_concat_agg FROM (
  SELECT [NULL, 1, 2, 3, 4] AS x
  UNION ALL SELECT NULL
  UNION ALL SELECT [5, 6]
  UNION ALL SELECT [7, 8, 9]
);

+-----------------------------------+
| array_concat_agg                  |
+-----------------------------------+
| [5, 6, 7, 8, 9, NULL, 1, 2, 3, 4] |
+-----------------------------------+

SELECT FORMAT("%T", ARRAY_CONCAT_AGG(x LIMIT 2)) AS array_concat_agg FROM (
  SELECT [NULL, 1, 2, 3, 4] AS x
  UNION ALL SELECT NULL
  UNION ALL SELECT [5, 6]
  UNION ALL SELECT [7, 8, 9]
);

+--------------------------+
| array_concat_agg         |
+--------------------------+
| [NULL, 1, 2, 3, 4, 5, 6] |
+--------------------------+

SELECT FORMAT("%T", ARRAY_CONCAT_AGG(x ORDER BY ARRAY_LENGTH(x) LIMIT 2)) AS array_concat_agg FROM (
  SELECT [NULL, 1, 2, 3, 4] AS x
  UNION ALL SELECT NULL
  UNION ALL SELECT [5, 6]
  UNION ALL SELECT [7, 8, 9]
);

+------------------+
| array_concat_agg |
+------------------+
| [5, 6, 7, 8, 9]  |
+------------------+

AVG

AVG([DISTINCT] expression)  [OVER (...)]

说明

返回非 NULL 输入值的平均值;如果输入包含 NaN,则返回 NaN

支持的参数类型

任何数字输入类型,例如 INT64。请注意,浮点输入类型的返回结果是不确定的,这意味着您在每次使用此函数时可能得到不同的结果。

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数。此子句目前与 AVG() 内的所有其他子句均不兼容。

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

返回的数据类型

  • 如果输入类型是 NUMERIC,则返回 NUMERIC。
  • FLOAT64

示例

SELECT AVG(x) as avg
FROM UNNEST([0, 2, NULL, 4, 4, 5]) as x;

+-----+
| avg |
+-----+
| 3   |
+-----+

SELECT AVG(DISTINCT x) AS avg
FROM UNNEST([0, 2, NULL, 4, 4, 5]) AS x;

+------+
| avg  |
+------+
| 2.75 |
+------+

SELECT
  x,
  AVG(x) OVER (ORDER BY x ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS avg
FROM UNNEST([0, 2, NULL, 4, 4, 5]) AS x;

+------+------+
| x    | avg  |
+------+------+
| NULL | NULL |
| 0    | 0    |
| 2    | 1    |
| 4    | 3    |
| 4    | 4    |
| 5    | 4.5  |
+------+------+

BIT_AND

BIT_AND(expression)

说明

expression 执行按位与运算并返回结果。

支持的参数类型

  • INT64

返回的数据类型

INT64

示例

SELECT BIT_AND(x) as bit_and FROM UNNEST([0xF001, 0x00A1]) as x;

+---------+
| bit_and |
+---------+
| 1       |
+---------+

BIT_OR

BIT_OR(expression)

说明

expression 执行按位或运算并返回结果。

支持的参数类型

  • INT64

返回的数据类型

INT64

示例

SELECT BIT_OR(x) as bit_or FROM UNNEST([0xF001, 0x00A1]) as x;

+--------+
| bit_or |
+--------+
| 61601  |
+--------+

BIT_XOR

BIT_XOR([DISTINCT] expression)

说明

expression 执行按位异或运算并返回结果。

支持的参数类型

  • INT64

可选子句

DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

返回的数据类型

INT64

示例

SELECT BIT_XOR(x) AS bit_xor FROM UNNEST([5678, 1234]) AS x;

+---------+
| bit_xor |
+---------+
| 4860    |
+---------+

SELECT BIT_XOR(x) AS bit_xor FROM UNNEST([1234, 5678, 1234]) AS x;
+---------+
| bit_xor |
+---------+
| 5678    |
+---------+

SELECT BIT_XOR(DISTINCT x) AS bit_xor FROM UNNEST([1234, 5678, 1234]) AS x;

+---------+
| bit_xor |
+---------+
| 4860    |
+---------+

COUNT

1.

COUNT(*)  [OVER (...)]

2.

COUNT([DISTINCT] expression)  [OVER (...)]

说明

  1. 返回输入中的行数。
  2. expression 的计算结果为 NULL 以外的任何值时,返回行数。

支持的参数类型

expression 可为任何数据类型。

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

返回数据类型

INT64

示例

SELECT
  COUNT(*) AS count_star,
  COUNT(x) AS count_x,
  COUNT(DISTINCT x) AS count_dist_x
FROM UNNEST([1, 4, NULL, 4, 5]) AS x;

+------------+---------+--------------+
| count_star | count_x | count_dist_x |
+------------+---------+--------------+
| 5          | 4       | 3            |
+------------+---------+--------------+

SELECT
  x,
  COUNT(*) OVER (PARTITION BY MOD(x, 3)) AS count_star,
  COUNT(x) OVER (PARTITION BY MOD(x, 3)) AS count_x,
  COUNT(DISTINCT x) OVER (PARTITION BY MOD(x, 3)) AS count_dist_x
FROM UNNEST([1, 4, NULL, 4, 5]) AS x;

+------+------------+---------+--------------+
| x    | count_star | count_x | count_dist_x |
+------+------------+---------+--------------+
| NULL | 1          | 0       | 0            |
| 1    | 3          | 3       | 2            |
| 4    | 3          | 3       | 2            |
| 4    | 3          | 3       | 2            |
| 5    | 1          | 1       | 1            |
+------+------------+---------+--------------+

COUNTIF

COUNTIF(expression)  [OVER (...)]

说明

返回 expressionTRUE 值计数。如果不存在任何输入行或所有行的 expression 计算结果均为 FALSE,则返回 0

支持的参数类型

BOOL

可选子句

OVER:指定一个窗口。请参见分析函数

返回数据类型

INT64

示例

SELECT COUNTIF(x<0) AS num_negative, COUNTIF(x>0) AS num_positive
FROM UNNEST([5, -2, 3, 6, -10, NULL, -7, 4, 0]) AS x;

+--------------+--------------+
| num_negative | num_positive |
+--------------+--------------+
| 3            | 4            |
+--------------+--------------+

SELECT
  x,
  COUNTIF(x<0) OVER (ORDER BY ABS(x) ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS num_negative
FROM UNNEST([5, -2, 3, 6, -10, NULL, -7, 4, 0]) AS x;

+------+--------------+
| x    | num_negative |
+------+--------------+
| NULL | 0            |
| 0    | 1            |
| -2   | 1            |
| 3    | 1            |
| 4    | 0            |
| 5    | 0            |
| 6    | 1            |
| -7   | 2            |
| -10  | 2            |
+------+--------------+

LOGICAL_AND

LOGICAL_AND(expression)

说明

返回所有非 NULL 表达式的逻辑与。如果不存在任何输入行或所有行的 expression 计算结果均为 NULL,则返回 NULL

支持的参数类型

BOOL

返回数据类型

BOOL

示例

SELECT LOGICAL_AND(x) as logical_and FROM UNNEST([true, false, true]) as x;

+-------------+
| logical_and |
+-------------+
| false       |
+-------------+

LOGICAL_OR

LOGICAL_OR(expression)

说明

返回所有非 NULL 表达式的逻辑或。如果不存在任何输入行或所有行的 expression 计算结果均为 NULL,则返回 NULL

支持的参数类型

BOOL

返回数据类型

BOOL

示例

SELECT LOGICAL_OR(x) as logical_or FROM UNNEST([true, false, true]) as x;

+------------+
| logical_or |
+------------+
| true       |
+------------+

MAX

MAX(expression)  [OVER (...)]

说明

返回非 NULL 表达式的最大值。如果不存在任何输入行或所有行的 expression 计算结果均为 NULL,则返回 NULL。如果输入包含 NaN,则返回 NaN

支持的参数类型

任意数据类型(ARRAYSTRUCT 除外)

可选子句

OVER:指定一个窗口。请参见分析函数

返回数据类型

与用作输入值的数据类型相同。

示例

SELECT MAX(x) AS max
FROM UNNEST([8, NULL, 37, 4, NULL, 55]) AS x;

+-----+
| max |
+-----+
| 55  |
+-----+

SELECT x, MAX(x) OVER (PARTITION BY MOD(x, 2)) AS max
FROM UNNEST([8, NULL, 37, 4, NULL, 55]) AS x;

+------+------+
| x    | max  |
+------+------+
| NULL | NULL |
| NULL | NULL |
| 8    | 8    |
| 4    | 8    |
| 37   | 55   |
| 55   | 55   |
+------+------+

MIN

MIN(expression)  [OVER (...)]

说明

返回非 NULL 表达式的最小值。如果不存在任何输入行或所有行的 expression 计算结果均为 NULL,则返回 NULL。如果输入包含 NaN,则返回 NaN

支持的参数类型

任意数据类型(ARRAYSTRUCT 除外)

可选子句

OVER:指定一个窗口。请参见分析函数

返回数据类型

与用作输入值的数据类型相同。

示例

SELECT MIN(x) AS min
FROM UNNEST([8, NULL, 37, 4, NULL, 55]) AS x;

+-----+
| min |
+-----+
| 4   |
+-----+

SELECT x, MIN(x) OVER (PARTITION BY MOD(x, 2)) AS min
FROM UNNEST([8, NULL, 37, 4, NULL, 55]) AS x;

+------+------+
| x    | min  |
+------+------+
| NULL | NULL |
| NULL | NULL |
| 8    | 4    |
| 4    | 4    |
| 37   | 37   |
| 55   | 37   |
+------+------+

STRING_AGG

STRING_AGG([DISTINCT] expression [, delimiter]  [ORDER BY key [{ASC|DESC}] [, ... ]]  [LIMIT n])
[OVER (...)]

说明

返回通过连接非 NULL 值获得的值(STRING 或 BYTES)。

如果指定了 delimiter,则连接的值由此分隔符进行分隔;否则使用逗号作为分隔符。

支持的参数类型

STRING BYTES

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数。此子句目前与 STRING_AGG() 内的所有其他子句均不兼容。

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

  3. ORDER BY:指定值的顺序。

    • 对于每个排序键,默认排序方向均为 ASC
    • NULL:在 ORDER BY 子句的上下文中,NULL 是可能的最小值;也就是说,NULL 在 ASC 排序方向中出现在最前位置,在 DESC 排序方向中出现在最后位置。
    • 浮点数据类型:如需了解排序和分组,请参阅浮点语义
    • 如果同时还指定了 DISTINCT,排序键必须与 expression 相同。
    • 如果未指定 ORDER BY,输出数组中的元素顺序是不确定的,这意味着您在每次使用此函数时可能得到不同的结果。
  4. LIMIT:指定结果中 expression 输入的最大数量。此上限适用于输入字符串数量,而非输入中的字符数量或字节数量。空字符串计为 1。NULL 字符串不计数。上限 n 必须是 INT64 常量。

返回数据类型

STRING BYTES

示例

SELECT STRING_AGG(fruit) AS string_agg
FROM UNNEST(["apple", NULL, "pear", "banana", "pear"]) AS fruit;

+------------------------+
| string_agg             |
+------------------------+
| apple,pear,banana,pear |
+------------------------+

SELECT STRING_AGG(fruit, " & ") AS string_agg
FROM UNNEST(["apple", NULL, "pear", "banana", "pear"]) AS fruit;

+------------------------------+
| string_agg                   |
+------------------------------+
| apple & pear & banana & pear |
+------------------------------+

SELECT STRING_AGG(DISTINCT fruit, " & ") AS string_agg
FROM UNNEST(["apple", NULL, "pear", "banana", "pear"]) AS fruit;

+-----------------------+
| string_agg            |
+-----------------------+
| apple & banana & pear |
+-----------------------+

SELECT STRING_AGG(fruit, " & " ORDER BY LENGTH(fruit)) AS string_agg
FROM UNNEST(["apple", NULL, "pear", "banana", "pear"]) AS fruit;

+------------------------------+
| string_agg                   |
+------------------------------+
| pear & pear & apple & banana |
+------------------------------+

SELECT STRING_AGG(fruit, " & " LIMIT 2) AS string_agg
FROM UNNEST(["apple", NULL, "pear", "banana", "pear"]) AS fruit;

+--------------+
| string_agg   |
+--------------+
| apple & pear |
+--------------+

SELECT STRING_AGG(DISTINCT fruit, " & " ORDER BY fruit DESC LIMIT 2) AS string_agg
FROM UNNEST(["apple", NULL, "pear", "banana", "pear"]) AS fruit;

+---------------+
| string_agg    |
+---------------+
| pear & banana |
+---------------+

SELECT
  fruit,
  STRING_AGG(fruit, " & ") OVER (ORDER BY LENGTH(fruit)) AS string_agg
FROM UNNEST(["apple", NULL, "pear", "banana", "pear"]) AS fruit;

+--------+------------------------------+
| fruit  | string_agg                   |
+--------+------------------------------+
| NULL   | NULL                         |
| pear   | pear & pear                  |
| pear   | pear & pear                  |
| apple  | pear & pear & apple          |
| banana | pear & pear & apple & banana |
+--------+------------------------------+

SUM

SUM([DISTINCT] expression)  [OVER (...)]

说明

返回非 NULL 值之和。

如果表达式是浮点值,则总和是不确定的,这意味着您在每次使用此函数时可能得到不同的结果。

支持的参数类型

任何支持的数字数据类型。

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

返回数据类型

  • 如果输入是整数,则返回 INT64。

  • 如果输入类型是 NUMERIC,则返回 NUMERIC。

  • 如果输入是浮点值,则返回 FLOAT64。

如果输入仅包含 NULL,则返回 NULL

如果输入包含 Inf,则返回 Inf

如果输入包含 -Inf,则返回 -Inf

如果输入包含 NaN,则返回 NaN

如果输入包含 Inf-Inf 的组合,则返回 NaN

示例

SELECT SUM(x) AS sum
FROM UNNEST([1, 2, 3, 4, 5, 4, 3, 2, 1]) AS x;

+-----+
| sum |
+-----+
| 25  |
+-----+

SELECT SUM(DISTINCT x) AS sum
FROM UNNEST([1, 2, 3, 4, 5, 4, 3, 2, 1]) AS x;

+-----+
| sum |
+-----+
| 15  |
+-----+

SELECT
  x,
  SUM(x) OVER (PARTITION BY MOD(x, 3)) AS sum
FROM UNNEST([1, 2, 3, 4, 5, 4, 3, 2, 1]) AS x;

+---+-----+
| x | sum |
+---+-----+
| 3 | 6   |
| 3 | 6   |
| 1 | 10  |
| 4 | 10  |
| 4 | 10  |
| 1 | 10  |
| 2 | 9   |
| 5 | 9   |
| 2 | 9   |
+---+-----+

SELECT
  x,
  SUM(DISTINCT x) OVER (PARTITION BY MOD(x, 3)) AS sum
FROM UNNEST([1, 2, 3, 4, 5, 4, 3, 2, 1]) AS x;

+---+-----+
| x | sum |
+---+-----+
| 3 | 3   |
| 3 | 3   |
| 1 | 5   |
| 4 | 5   |
| 4 | 5   |
| 1 | 5   |
| 2 | 7   |
| 5 | 7   |
| 2 | 7   |
+---+-----+

统计聚合函数

BigQuery 支持以下统计聚合函数。

CORR

CORR(X1, X2)  [OVER (...)]

说明

返回一组数字对的皮尔逊相关系数。针对每个数字对,第一个数字都是因变量,第二个数字都是自变量。返回结果介于 -11 之间。结果如果为 0,则表示不相关。

此函数会忽略包含一个或多个 NULL 值的任何输入对。如果非 NULL 值的输入对少于两个,此函数会返回 NULL。

支持的输入类型

FLOAT64

可选子句

OVER:指定一个窗口。请参阅分析函数

返回数据类型

FLOAT64

COVAR_POP

COVAR_POP(X1, X2)  [OVER (...)]

说明

返回一组数字对的总体协方差。第一个数字是因变量;第二个数字是自变量。返回结果介于 -Inf+Inf 之间。

此函数会忽略包含一个或多个 NULL 值的任何输入对。如果不存在没有 NULL 值的输入对,此函数会返回 NULL。如果没有 NULL 值的输入对仅有一个,则此函数返回 0。

支持的输入类型

FLOAT64

可选子句

OVER:指定一个窗口。请参阅分析函数

返回数据类型

FLOAT64

COVAR_SAMP

COVAR_SAMP(X1, X2)  [OVER (...)]

说明

返回一组数字对的样本协方差。第一个数字是因变量;第二个数字是自变量。返回结果介于 -Inf+Inf 之间。

此函数会忽略包含一个或多个 NULL 值的任何输入对。如果非 NULL 值的输入对少于两个,此函数会返回 NULL。

支持的输入类型

FLOAT64

可选子句

OVER:指定一个窗口。请参阅分析函数

返回数据类型

FLOAT64

STDDEV_POP

STDDEV_POP([DISTINCT] expression)  [OVER (...)]

说明

返回值的总体(偏置)标准偏差。返回结果介于 0+Inf 之间。

此函数会忽略任何 NULL 输入。如果所有输入均被忽略,此函数会返回 NULL。

如果此函数收到单个非 NULL 输入,它会返回 0

支持的输入类型

FLOAT64

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数。此子句目前与 STDDEV_POP() 内的所有其他子句均不兼容。

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

返回数据类型

FLOAT64

STDDEV_SAMP

STDDEV_SAMP([DISTINCT] expression)  [OVER (...)]

说明

返回值的样本(无偏差)标准差。返回结果介于 0+Inf 之间。

此函数会忽略任何 NULL 输入。如果非 NULL 输入少于两个,则此函数返回 NULL。

支持的输入类型

FLOAT64

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数。此子句目前与 STDDEV_SAMP() 内的所有其他子句均不兼容。

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

返回数据类型

FLOAT64

STDDEV

STDDEV([DISTINCT] expression)  [OVER (...)]

说明

STDDEV_SAMP 的别名。

VAR_POP

VAR_POP([DISTINCT] expression)  [OVER (...)]

说明

返回值的总体(偏差)方差。返回结果介于 0+Inf 之间。

此函数会忽略任何 NULL 输入。如果所有输入均被忽略,此函数会返回 NULL。

如果此函数收到单个非 NULL 输入,它会返回 0

支持的输入类型

FLOAT64

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数。此子句目前与 VAR_POP() 内的所有其他子句均不兼容。

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

返回数据类型

FLOAT64

VAR_SAMP

VAR_SAMP([DISTINCT] expression)  [OVER (...)]

说明

返回值的样本(无偏置)方差。返回结果介于 0+Inf 之间。

此函数会忽略任何 NULL 输入。如果非 NULL 输入少于两个,则此函数返回 NULL。

支持的输入类型

FLOAT64

可选子句

子句按照以下顺序应用

  1. OVER:指定一个窗口。请参见分析函数。此子句目前与 VAR_SAMP() 内的所有其他子句均不兼容。

  2. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

返回数据类型

FLOAT64

VARIANCE

VARIANCE([DISTINCT] expression)  [OVER (...)]

说明

VAR_SAMP 的别名。

近似聚合函数

近似聚合函数在内存使用量和时间方面具有可扩展的特点,但其生成的结果为近似结果,而非准确结果。要详细了解背景信息,请参阅近似聚合

APPROX_COUNT_DISTINCT

APPROX_COUNT_DISTINCT(expression)

说明

返回 COUNT(DISTINCT expression) 的近似结果。返回值为统计预计值 - 而不一定是实际值。

此函数的准确性低于 COUNT(DISTINCT expression),但在处理海量输入时性能较为出众。

支持的参数类型

任意数据类型(ARRAYSTRUCT 除外

返回的数据类型

INT64

示例

SELECT APPROX_COUNT_DISTINCT(x) as approx_distinct
FROM UNNEST([0, 1, 1, 2, 3, 5]) as x;

+-----------------+
| approx_distinct |
+-----------------+
| 5               |
+-----------------+

APPROX_QUANTILES

APPROX_QUANTILES([DISTINCT] expression, number [{IGNORE|RESPECT} NULLS])

说明

返回一组 expression 值的近似边界,其中 number 表示要创建的分位数的数量。此函数返回一个数组,该数组中包含 number + 1 个元素,其中第一个元素是近似最小值,最后一个元素是近似最大值。

支持的参数类型

expression 可以是任意受支持的数据类型(ARRAYSTRUCT 除外

number 必须是 INT64 值。

可选子句

子句按照以下顺序应用

  1. DISTINCTexpression 的每个不同的值均仅聚合到结果中一次。

  2. IGNORE NULLSRESPECT NULLS:如果指定了 IGNORE NULLS 或者未指定任一项,则从结果中排除 NULL 值。如果指定了 RESPECT NULLS,结果中会包含 NULL 值(但如果最终查询结果中的数组包含 NULL 元素,则会报错)。

返回的数据类型

expression 参数指定的类型的数组。

如果不存在任何输入行或所有行的 expression 计算结果均为 NULL,则返回 NULL

示例

SELECT APPROX_QUANTILES(x, 2) AS approx_quantiles
FROM UNNEST([NULL, NULL, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10]) AS x;

+------------------+
| approx_quantiles |
+------------------+
| [1, 5, 10]       |
+------------------+

SELECT APPROX_QUANTILES(x, 100)[OFFSET(90)] AS percentile_90
FROM UNNEST([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) AS x;

+---------------+
| percentile_90 |
+---------------+
| 9             |
+---------------+

SELECT APPROX_QUANTILES(DISTINCT x, 2) AS approx_quantiles
FROM UNNEST([NULL, NULL, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10]) AS x;

+------------------+
| approx_quantiles |
+------------------+
| [1, 6, 10]       |
+------------------+

SELECT FORMAT("%T", APPROX_QUANTILES(x, 2 RESPECT NULLS)) AS approx_quantiles
FROM UNNEST([NULL, NULL, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10]) AS x;

+------------------+
| approx_quantiles |
+------------------+
| [NULL, 4, 10]    |
+------------------+

SELECT FORMAT("%T", APPROX_QUANTILES(DISTINCT x, 2 RESPECT NULLS)) AS approx_quantiles
FROM UNNEST([NULL, NULL, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10]) AS x;

+------------------+
| approx_quantiles |
+------------------+
| [NULL, 6, 10]    |
+------------------+

APPROX_TOP_COUNT

APPROX_TOP_COUNT(expression, number)

说明

返回 expression 的近似顶级元素。number 参数指定返回的元素数量。

支持的参数类型

expression 可以是 GROUP BY 子句支持的任意数据类型。

number 必须是 INT64 值。

返回的数据类型

返回 ARRAY 类型的结果,其元素为 STRUCT 类型。该 STRUCT 包含两个字段。第一个字段(名为 value)包含一个输入值。第二个字段(名为 count)包含一个 INT64 值,指定 value 返回的次数。

如果不存在任何输入行,则返回 NULL

示例

SELECT APPROX_TOP_COUNT(x, 2) as approx_top_count
FROM UNNEST(["apple", "apple", "pear", "pear", "pear", "banana"]) as x;

+-------------------------+
| approx_top_count        |
+-------------------------+
| [{pear, 3}, {apple, 2}] |
+-------------------------+

NULL 处理

APPROX_TOP_COUNT 不会忽略输入中的 NULL。例如:

SELECT APPROX_TOP_COUNT(x, 2) as approx_top_count
FROM UNNEST([NULL, "pear", "pear", "pear", "apple", NULL]) as x;

+------------------------+
| approx_top_count       |
+------------------------+
| [{pear, 3}, {NULL, 2}] |
+------------------------+

APPROX_TOP_SUM

APPROX_TOP_SUM(expression, weight, number)

说明

根据指定 weight 的总和,返回 expression 的近似顶级元素。number 参数指定返回的元素数量。

如果 weight 输入为负或者 NaN,此函数会返回错误。

支持的参数类型

expression 可以是 GROUP BY 子句支持的任意数据类型。

weight 必须为以下类型之一:

  • INT64
  • FLOAT64

number 必须是 INT64 值。

返回的数据类型

返回类型为 STRUCT 的 ARRAY 结果。该 STRUCT 包含两个字段:valuesumvalue 字段包含输入表达式的值。sum 字段与 weight 类型相同,是与 value 字段关联的输入权重的近似总和。

如果不存在任何输入行,则返回 NULL

示例

SELECT APPROX_TOP_SUM(x, weight, 2) AS approx_top_sum FROM
UNNEST([
  STRUCT("apple" AS x, 3 AS weight),
  ("pear", 2),
  ("apple", 0),
  ("banana", 5),
  ("pear", 4)
]);

+--------------------------+
| approx_top_sum           |
+--------------------------+
| [{pear, 6}, {banana, 5}] |
+--------------------------+

NULL 处理

APPROX_TOP_SUM 不会忽略 expressionweight 参数的 NULL 值。

SELECT APPROX_TOP_SUM(x, weight, 2) AS approx_top_sum FROM
UNNEST([STRUCT("apple" AS x, NULL AS weight), ("pear", 0), ("pear", NULL)]);

+----------------------------+
| approx_top_sum             |
+----------------------------+
| [{pear, 0}, {apple, NULL}] |
+----------------------------+
SELECT APPROX_TOP_SUM(x, weight, 2) AS approx_top_sum FROM
UNNEST([STRUCT("apple" AS x, 0 AS weight), (NULL, 2)]);

+-------------------------+
| approx_top_sum          |
+-------------------------+
| [{NULL, 2}, {apple, 0}] |
+-------------------------+
SELECT APPROX_TOP_SUM(x, weight, 2) AS approx_top_sum FROM
UNNEST([STRUCT("apple" AS x, 0 AS weight), (NULL, NULL)]);

+----------------------------+
| approx_top_sum             |
+----------------------------+
| [{apple, 0}, {NULL, NULL}] |
+----------------------------+

HyperLogLog++ 函数

BigQuery 支持使用 HyperLogLog++ 算法的以下近似聚合函数。如需了解近似聚合函数的工作原理,请参阅近似聚合

HLL_COUNT.INIT

HLL_COUNT.INIT(input [, precision])

说明

这个聚合函数接受一个或多个 input 值,并将这些值聚合到一个 HyperLogLog++ 草图 (sketch)。每个草图均使用 BYTES 数据类型表示。随后您可以使用 HLL_COUNT.MERGEHLL_COUNT.MERGE_PARTIAL 合并草图。如果不需要合并,您可以使用 HLL_COUNT.EXTRACT 从草图中提取不同值的最终计数。

input 可以是以下各项之一:

  • INT64
  • STRING
  • BYTES

此函数支持可选参数 precision。此参数用于定义估计值的准确性,定义的准确性越高处理草图或将草图存储在磁盘上所需的内存就越多。下表展示了允许的精度值、每组最大草图大小,以及典型精度的置信区间 (CI):

精度 最大草图大小 (KiB) 65% CI 95% CI 99% CI
10 1 ±1.63% ±3.25% ±6.50%
11 2 ±1.15% ±2.30% ±4.60%
12 4 ±0.81% ±1.63% ±3.25%
13 8 ±0.57% ±1.15% ±1.72%
14 16 ±0.41% ±0.81% ±1.22%
15(默认) 32 ±0.29% ±0.57% ±0.86%
16 64 ±0.20% ±0.41% ±0.61%
17 128 ±0.14% ±0.29% ±0.43%
18 256 ±0.10% ±0.20% ±0.41%
19 512 ±0.07% ±0.14% ±0.29%
20 1024 ±0.05% ±0.10% ±0.20%
21 2048 ±0.04% ±0.07% ±0.14%
22 4096 ±0.03% ±0.05% ±0.10%
23 8192 ±0.02% ±0.04% ±0.07%
24 16384 ±0.01% ±0.03% ±0.05%

如果输入是 NULL,则此函数会返回 NULL。

如需了解详情,请参阅 HyperLogLog 实践:一种先进基数估计算法的算法工程

支持的输入类型

BYTES

返回类型

BYTES

示例

SELECT
  HLL_COUNT.INIT(respondent) AS respondents_hll,
  flavor,
  country
FROM UNNEST([
  STRUCT(1 AS respondent, "Vanilla" AS flavor, "CH" AS country),
  (1, "Chocolate", "CH"),
  (2, "Chocolate", "US"),
  (2, "Strawberry", "US")])
GROUP BY flavor, country;

HLL_COUNT.MERGE

HLL_COUNT.MERGE(sketch)

说明

这个聚合函数会计算多组 HyperLogLog++ 草图的并集,并返回其基数。

每个 sketch 都必须具有相同的精度,并按照相同的类型初始化。尝试合并具有不同精度或用于不同类型的草图会引发错误。例如,您不能将使用 INT64 数据初始化的草图与使用 STRING 数据初始化的草图合并。

在合并草图时,此函数会忽略 NULL 值。如果合并了零行,或者只有 NULL 值发生合并,此函数会返回 0

支持的输入类型

BYTES

返回类型

INT64

示例

SELECT HLL_COUNT.MERGE(respondents_hll) AS num_respondents, flavor
FROM (
  SELECT
    HLL_COUNT.INIT(respondent) AS respondents_hll,
    flavor,
    country
  FROM UNNEST([
    STRUCT(1 AS respondent, "Vanilla" AS flavor, "CH" AS country),
    (1, "Chocolate", "CH"),
    (2, "Chocolate", "US"),
    (2, "Strawberry", "US")])
  GROUP BY flavor, country)
GROUP BY flavor;

HLL_COUNT.MERGE_PARTIAL

HLL_COUNT.MERGE_PARTIAL(sketch)

说明

这个聚合函数会接受一个或多个 HyperLogLog++ sketch 输入,并将它们合并到一个新草图。

如果无输入或所有输入均为 NULL,此函数返回 NULL。

支持的输入类型

BYTES

返回类型

BYTES

示例

SELECT HLL_COUNT.MERGE_PARTIAL(respondents_hll) AS num_respondents, flavor
FROM (
  SELECT
    HLL_COUNT.INIT(respondent) AS respondents_hll,
    flavor,
    country
  FROM UNNEST([
    STRUCT(1 AS respondent, "Vanilla" AS flavor, "CH" AS country),
    (1, "Chocolate", "CH"),
    (2, "Chocolate", "US"),
    (2, "Strawberry", "US")])
  GROUP BY flavor, country)
GROUP BY flavor;

HLL_COUNT.EXTRACT

HLL_COUNT.EXTRACT(sketch)

说明

这个标量函数会提取一个 HyperLogLog++ 草图的基数估计值。

如果 sketch 是 NULL,此函数返回的基数估计值为 0

支持的输入类型

BYTES

返回类型

INT64

示例

SELECT
  flavor,
  country,
  HLL_COUNT.EXTRACT(respondents_hll) AS num_respondents
FROM (
  SELECT
    HLL_COUNT.INIT(respondent) AS respondents_hll,
    flavor,
    country
  FROM UNNEST([
    STRUCT(1 AS respondent, "Vanilla" AS flavor, "CH" AS country),
    (1, "Chocolate", "CH"),
    (2, "Chocolate", "US"),
    (2, "Strawberry", "US")])
  GROUP BY flavor, country);

+------------+---------+-----------------+
| flavor     | country | num_respondents |
+------------+---------+-----------------+
| Vanilla    | CH      | 1               |
| Chocolate  | CH      | 1               |
| Chocolate  | US      | 1               |
| Strawberry | US      | 1               |
+------------+---------+-----------------+

编号函数

以下部分介绍了 BigQuery 支持的编号函数。supports. 编号函数是分析函数的一部分。 如需了解分析函数的工作原理,请参阅分析函数概念。如需了解编号函数的工作原理,请参阅编号函数概念

OVER 子句要求:

  • PARTITION BY:可选。
  • ORDER BY:必须(ROW_NUMBER() 除外)。
  • window_frame_clause:不允许。

RANK

说明

返回排序分区中各行的序数(从 1 开始)。所有对等行均获得相同的排序值。下一行或下一组对等行获得的排序值按照具有先前排序值的对等数量递增,而非按 DENSE_RANK 递增,后者始终按 1 递增。

支持的参数类型

INT64

DENSE_RANK

说明

返回窗口分区中各行的序数(从 1 开始)排名。所有对等行获得相同的排名值,后续排名值按 1 递增。

支持的参数类型

INT64

PERCENT_RANK

说明

返回定义为 (RK-1)/(NR-1) 的百分位排名,其中 RK 是行的 RANK,NR 是分区内的行数。如果 NR=1,则返回 0。

支持的参数类型

FLOAT64

CUME_DIST

说明

返回一行的相对排名,定义为 NP/NR。NP 定义为在当前行之前或与当前行对等的行数。NR 是分区内的行数。

支持的参数类型

FLOAT64

NTILE

NTILE(constant_integer_expression)

说明

此函数根据行排序将行划分为 constant_integer_expression 个存储分区,返回分配给各行的存储分区编号(从 1 开始)。存储分区内的行数最多可以相差 1。从存储分区 1 开始,为每个存储分区分配一个剩余值(剩余的行数除以存储分区数)。如果 constant_integer_expression 计算结果为 NULL、0 或负数,则会引发错误。

支持的参数类型

INT64

ROW_NUMBER

说明

不需要 ORDER BY 子句。返回每个排序分区中各行的顺序行序号(从 1 开始)。如果未指定 ORDER BY 子句,则结果是非确定性的。

支持的参数类型

INT64

位函数

BigQuery 支持以下位函数。

BIT_COUNT

BIT_COUNT(expression)

说明

expression 输入必须是整数或 BYTES。

返回在输入 expression 中设置的位数。如果是带符号整数,则为补码的位数。

返回数据类型

INT64

示例

SELECT a, BIT_COUNT(a) AS a_bits, FORMAT("%T", b) as b, BIT_COUNT(b) AS b_bits
FROM UNNEST([
  STRUCT(0 AS a, b'' AS b), (0, b'\x00'), (5, b'\x05'), (8, b'\x00\x08'),
  (0xFFFF, b'\xFF\xFF'), (-2, b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE'),
  (-1, b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'),
  (NULL, b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF')
]) AS x;

+-------+--------+---------------------------------------------+--------+
| a     | a_bits | b                                           | b_bits |
+-------+--------+---------------------------------------------+--------+
| 0     | 0      | b""                                         | 0      |
| 0     | 0      | b"\x00"                                     | 0      |
| 5     | 2      | b"\x05"                                     | 2      |
| 8     | 1      | b"\x00\x08"                                 | 1      |
| 65535 | 16     | b"\xff\xff"                                 | 16     |
| -2    | 63     | b"\xff\xff\xff\xff\xff\xff\xff\xfe"         | 63     |
| -1    | 64     | b"\xff\xff\xff\xff\xff\xff\xff\xff"         | 64     |
| NULL  | NULL   | b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" | 80     |
+-------+--------+---------------------------------------------+--------+

数学函数

所有数学函数都具有以下行为:

  • 如果任一输入参数为 NULL,则返回 NULL
  • 如果任一参数为 NaN,则返回 NaN

ABS

ABS(X)

说明

计算绝对值。如果参数是整数,而输出值无法用同一类型表示,则返回一个错误;仅最大负输入值(不具有正数表示形式)会发生此情况。对 +/-inf 参数返回 +inf

SIGN

SIGN(X)

说明

分别对负参数、零和正参数返回 -1、0 或 +1。对于浮点参数,此函数不区分正零和负零。对 NaN 参数返回 NaN

IS_INF

IS_INF(X)

说明

如果值为正无穷或负无穷,则返回 TRUE。对 NULL 输入返回 NULL

IS_NAN

IS_NAN(X)

说明

如果值为 NaN 值,则返回 TRUE。对 NULL 输入返回 NULL

IEEE_DIVIDE

IEEE_DIVIDE(X, Y)

说明

用 X 除以 Y;此函数始终有效。返回 FLOAT64。不同于除法运算符 (/),如果除数为零或溢出,此函数不会生成错误。

特殊情况:

  • 如果结果溢出,则返回 +/-inf
  • 如果 Y=0 且 X=0,则返回 NaN
  • 如果 Y=0 且 X!=0,则返回 +/-inf
  • 如果 X = +/-inf 且 Y = +/-inf,则返回 NaN

下表进一步说明了 IEEE_DIVIDE 的行为。

IEEE_DIVIDE 的特殊情况

下表列出了 IEEE_DIVIDE 的特殊情况。

分子数据类型 (X) 分母数据类型 (Y) 结果值
除 0 外的任何值 0 +/-inf
0 0 NaN
0 NaN NaN
NaN 0 NaN
+/-inf +/-inf NaN

RAND

RAND()

说明

在范围 [0, 1)(包含 0,不包含 1)内生成 FLOAT64 类型的伪随机值。

SQRT

SQRT(X)

说明

计算 X 的平方根。如果 X 小于 0,则生成错误。如果 X 为 +inf,则返回 +inf

POW

POW(X, Y)

说明

返回 X 的 Y 次幂的值。如果结果下溢且不可表示,则函数返回值 0。如果下述任一条件为 true,则返回一个错误:

  • X 是小于 0 的有限值且 Y 是非整数
  • X 是 0 且 Y 是小于 0 的有限值

下表进一步说明了 POW() 的行为。

POWER

POWER(X, Y)

说明

相当于 POW()

POW(X, Y)POWER(X, Y) 的特殊情况

下面是 POW(X, Y)POWER(X, Y) 的特殊情况。

X Y POW(X, Y) 或 POWER(X, Y)
1.0 任何值(包括 NaN 1.0
任何值(包括 NaN 0 1.0
-1.0 +/-inf 1.0
ABS(X) < 1 -inf +inf
ABS(X) > 1 -inf 0
ABS(X) < 1 +inf 0
ABS(X) > 1 +inf +inf
-inf Y < 0 0
-inf Y > 0 如果 Y 为奇整数,则为 -inf;否则为 +inf
+inf Y < 0 0
+inf Y > 0 +inf

EXP

EXP(X)

说明

计算 e 的 X 次幂,也被称为自然指数函数。如果结果下溢,此函数返回 0。如果结果上溢,则生成错误。如果 X 是 +/-inf,则此函数返回 +inf 或 0。

LN

LN(X)

说明

计算 X 的自然对数。如果 X 小于或等于 0,则生成错误。如果 X 是 +inf,则此函数返回 +inf

LOG

LOG(X [, Y])

说明

如果只存在 X,则 LOG 相当于 LN。如果还存在 Y,则 LOG 计算以 Y 为底数的 X 的对数。在以下情况下将生成错误:

  • X 小于或等于 0
  • Y 等于 1.0
  • Y 小于或等于 0。

下表进一步说明了 LOG(X, Y) 的行为。

LOG(X, Y) 的特殊情况

X Y LOG(X, Y)
-inf 任意值 NaN
任意值 +inf NaN
+inf 0.0 Y < 1.0 -inf
+inf Y > 1.0 +inf

LOG10

LOG10(X)

说明

LOG 类似,但计算的是以 10 为底数的对数。

GREATEST

GREATEST(X1,...,XN)

说明

如果任一输入为 NULL,则返回 NULL。如果任一输入为 NaN,则返回 NaN。否则根据比较得出更大值,返回 X1,...,XN 中的最大值。

LEAST

LEAST(X1,...,XN)

说明

如果任一输入为 NULL,则返回 NULL。如果任一输入为 NaN,则返回 NaN。否则根据比较得出更小值,返回 X1,...,XN 中的最小值。

DIV

DIV(X, Y)

说明

返回 X 被 Y 整除的结果。如果除数为 0,则返回一个错误。除数为 -1 时可能溢出。请查看下表,了解可能的结果类型。

SAFE_DIVIDE

SAFE_DIVIDE(X, Y)

说明

等同于除法运算符 (/),但如果发生错误,则返回 NULL,例如除以 0 时的错误。

SAFE_MULTIPLY

SAFE_MULTIPLY(X, Y)

说明

等同于乘法运算符 (*),但如果发生溢出,则返回 NULL

SAFE_NEGATE

SAFE_NEGATE(X)

说明

等同于一元取反运算符 (-),但如果发生溢出,则返回 NULL

SAFE_ADD

SAFE_ADD(X, Y)

说明

等同于加法运算符 (+),但如果发生溢出,则返回 NULL

SAFE_SUBTRACT

SAFE_SUBTRACT(X, Y)

说明

等同于减法运算符 (-),但如果发生溢出,则返回 NULL

MOD

MOD(X, Y)

说明

取模函数:返回 X 除以 Y 的余数。返回值的符号与 X 相同。如果 Y 为 0,则生成一个错误。请查看下表,了解可能的结果类型。

ROUND

ROUND(X [, N])

说明

如果只存在 X,则 ROUND 将 X 向最近的整数舍入。如果存在 N,ROUND 将 X 舍入到小数点后 N 个小数位。如果 N 为负数,则 ROUND 将舍掉小数点取整。则向远离 0 的方向按中间数舍入。如果发生溢出,则生成错误。

TRUNC

TRUNC(X [, N])

说明

如果只存在 X,则 TRUNC 将 X 向最近的整数舍入,且此整数的绝对值不超过 X 的绝对值。如果还存在 N,则 TRUNC 的行为类似于 ROUND(X, N),但始终向 0 舍入且永不溢出。

CEIL

CEIL(X)

说明

返回不小于 X 的最小整数值(FLOAT64 类型)。

CEILING

CEILING(X)

说明

相当于 CEIL(X)

FLOOR

FLOOR(X)

说明

返回不大于 X 的最大整数值(FLOAT64 类型)。

舍入函数行为示例

BigQuery 舍入函数的行为示例:

输入“X” ROUND(X) TRUNC(X) CEIL(X) FLOOR(X)
2.0 2.0 2.0 2.0 2.0
2.3 2.0 2.0 3.0 2.0
2.8 3.0 2.0 3.0 2.0
2.5 3.0 2.0 3.0 2.0
-2.3 -2.0 -2.0 -2.0 -3.0
-2.8 -3.0 -2.0 -2.0 -3.0
-2.5 -3.0 -2.0 -2.0 -3.0
0 0 0 0 0
+/-inf +/-inf +/-inf +/-inf +/-inf
NaN NaN NaN NaN NaN

COS

COS(X)

说明

计算 X 的余弦,其中 X 以弧度指定。永不会失败。

COSH

COSH(X)

说明

计算 X 的双曲余弦,其中 X 以弧度指定。 如果发生溢出,则生成错误。

ACOS

ACOS(X)

说明

计算 X 的反余弦的主值。返回值在 [0,π] 范围内。如果 X 是超出 [-1, 1] 范围的值,则生成错误。

ACOSH

ACOSH(X)

说明

计算 X 的反双曲余弦。如果 X 是小于 1 的值,则生成错误。

SIN

SIN(X)

说明

计算 X 的正弦,其中 X 以弧度指定。永不失效。

SINH

SINH(X)

说明

计算 X 的双曲正弦,其中 X 以弧度指定。如果发生溢出,则生成错误。

ASIN

ASIN(X)

说明

计算 X 的反正弦的主值。返回值在 [-π/2,π/2] 范围内。如果 X 是超出 [-1, 1] 范围的值,则生成错误。

ASINH

ASINH(X)

说明

计算 X 的反双曲正弦。不会失效。

TAN

TAN(X)

说明

计算 X 的正切,其中 X 以弧度指定。如果发生溢出,则生成错误。

TANH

TANH(X)

说明

计算 X 的双曲正切,其中 X 以弧度指定。不会失效。

ATAN

ATAN(X)

说明

计算 X 的反正切的主值。返回值在 [-π/2,π/2] 范围内。不会失效。

ATANH

ATANH(X)

说明

计算 X 的反双曲正切。如果 X 是超出 [-1, 1] 范围的值,则生成错误。

ATAN2

ATAN2(Y, X)

说明

通过使用两个参数的符号确定象限,计算 Y/X 的反正切的主值。返回值在 [-π,π] 范围内。下表进一步说明了此函数的行为。

ATAN2() 的特殊情况

Y X ATAN2(Y, X)
NaN 任意值 NaN
任意值 NaN NaN
0 0 0、π 或 -π(取决于 X 和 Y 的符号)
有限值 -inf π 或 -π(取决于 Y 的符号)
有限值 +inf 0
+/-inf 有限值 π/2 或 π/2(取决于 Y 的符号)
+/-inf -inf ¾π 或 -¾π(取决于 Y 的符号)
+/-inf +inf π/4 或 -π/4(取决于 Y 的符号)

三角函数和双曲线舍入函数的特殊情况

X COS(X) COSH(X) ACOS(X) ACOSH(X) SIN(X) SINH(X) ASIN(X) ASINH(X) TAN(X) TANH(X) ATAN(X) ATANH(X)
+/-inf NaN =+inf NaN =+inf NaN =+inf NaN =+inf NaN =+1.0 π/2 NaN
-inf NaN =+inf NaN NaN NaN -inf NaN -inf NaN -1.0 -π/2 NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

以下部分介绍了 BigQuery 支持的导航函数。导航函数是分析函数的子集。如需了解分析函数的工作原理,请参阅分析函数概念。如需了解导航函数的工作原理,请参阅导航函数概念

FIRST_VALUE

FIRST_VALUE (value_expression [{RESPECT | IGNORE} NULLS])

说明

返回当前窗口框架中第一行的 value_expression 值。

除非存在 IGNORE NULLS,否则此函数在计算中包含 NULL 值。如果存在 IGNORE NULLS,此函数会从计算中排除 NULL 值。

支持的参数类型

value_expression 可以是表达式支持的任意返回数据类型。

返回数据类型

任意

示例

以下示例计算各部门的最快时间。

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  FORMAT_TIMESTAMP('%X', finish_time) AS finish_time,
  division,
  FORMAT_TIMESTAMP('%X', fastest_time) AS fastest_time,
  TIMESTAMP_DIFF(finish_time, fastest_time, SECOND) AS delta_in_seconds
FROM (
  SELECT name,
  finish_time,
  division,
  FIRST_VALUE(finish_time)
    OVER (PARTITION BY division ORDER BY finish_time ASC
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS fastest_time
  FROM finishers);

+-----------------+-------------+----------+--------------+------------------+
| name            | finish_time | division | fastest_time | delta_in_seconds |
+-----------------+-------------+----------+--------------+------------------+
| Carly Forte     | 03:08:58    | F25-29   | 03:08:58     | 0                |
| Sophia Liu      | 02:51:45    | F30-34   | 02:51:45     | 0                |
| Nikki Leith     | 02:59:01    | F30-34   | 02:51:45     | 436              |
| Jen Edwards     | 03:06:36    | F30-34   | 02:51:45     | 891              |
| Meghan Lederer  | 03:07:41    | F30-34   | 02:51:45     | 956              |
| Lauren Reasoner | 03:10:14    | F30-34   | 02:51:45     | 1109             |
| Lisa Stelzner   | 02:54:11    | F35-39   | 02:54:11     | 0                |
| Lauren Matthews | 03:01:17    | F35-39   | 02:54:11     | 426              |
| Desiree Berry   | 03:05:42    | F35-39   | 02:54:11     | 691              |
| Suzy Slane      | 03:06:24    | F35-39   | 02:54:11     | 733              |
+-----------------+-------------+----------+--------------+------------------+

LAST_VALUE

LAST_VALUE (value_expression [{RESPECT | IGNORE} NULLS])

说明

返回当前窗口框架中最后一行的 value_expression 值。

除非存在 IGNORE NULLS,否则此函数在计算中包含 NULL 值。如果存在 IGNORE NULLS,此函数会从计算中排除 NULL 值。

支持的参数类型

value_expression 可以是表达式支持的任意返回数据类型。

返回数据类型

任意

示例

以下示例计算各部门的最慢时间。

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  FORMAT_TIMESTAMP('%X', finish_time) AS finish_time,
  division,
  FORMAT_TIMESTAMP('%X', slowest_time) AS slowest_time,
  TIMESTAMP_DIFF(slowest_time, finish_time, SECOND) AS delta_in_seconds
FROM (
  SELECT name,
  finish_time,
  division,
  LAST_VALUE(finish_time)
    OVER (PARTITION BY division ORDER BY finish_time ASC
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS slowest_time
  FROM finishers);

+-----------------+-------------+----------+--------------+------------------+
| name            | finish_time | division | slowest_time | delta_in_seconds |
+-----------------+-------------+----------+--------------+------------------+
| Carly Forte     | 03:08:58    | F25-29   | 03:08:58     | 0                |
| Sophia Liu      | 02:51:45    | F30-34   | 03:10:14     | 1109             |
| Nikki Leith     | 02:59:01    | F30-34   | 03:10:14     | 673              |
| Jen Edwards     | 03:06:36    | F30-34   | 03:10:14     | 218              |
| Meghan Lederer  | 03:07:41    | F30-34   | 03:10:14     | 153              |
| Lauren Reasoner | 03:10:14    | F30-34   | 03:10:14     | 0                |
| Lisa Stelzner   | 02:54:11    | F35-39   | 03:06:24     | 733              |
| Lauren Matthews | 03:01:17    | F35-39   | 03:06:24     | 307              |
| Desiree Berry   | 03:05:42    | F35-39   | 03:06:24     | 42               |
| Suzy Slane      | 03:06:24    | F35-39   | 03:06:24     | 0                |
+-----------------+-------------+----------+--------------+------------------+

NTH_VALUE

NTH_VALUE (value_expression, constant_integer_expression [{RESPECT | IGNORE} NULLS])

说明

返回当前窗口框架中第 N 行的 value_expression 值,其中的 N 由 constant_integer_expression 定义。如果不存在此类行,则返回 NULL。

除非存在 IGNORE NULLS,否则此函数在计算中包含 NULL 值。如果存在 IGNORE NULLS,此函数会从计算中排除 NULL 值。

支持的参数类型

  • value_expression 可以是表达式支持的任意返回数据类型。
  • constant_integer_expression 可以是返回整数的任意常量表达式。

返回数据类型

任意

示例

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  FORMAT_TIMESTAMP('%X', finish_time) AS finish_time,
  division,
  FORMAT_TIMESTAMP('%X', fastest_time) AS fastest_time,
  FORMAT_TIMESTAMP('%X', second_fastest) AS second_fastest
FROM (
  SELECT name,
  finish_time,
  division,finishers,
  FIRST_VALUE(finish_time)
    OVER w1 AS fastest_time,
  NTH_VALUE(finish_time, 2)
    OVER w1 as second_fastest
  FROM finishers
  WINDOW w1 AS (
    PARTITION BY division ORDER BY finish_time ASC
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING));

+-----------------+-------------+----------+--------------+----------------+
| name            | finish_time | division | fastest_time | second_fastest |
+-----------------+-------------+----------+--------------+----------------+
| Carly Forte     | 03:08:58    | F25-29   | 03:08:58     | NULL           |
| Sophia Liu      | 02:51:45    | F30-34   | 02:51:45     | 02:59:01       |
| Nikki Leith     | 02:59:01    | F30-34   | 02:51:45     | 02:59:01       |
| Jen Edwards     | 03:06:36    | F30-34   | 02:51:45     | 02:59:01       |
| Meghan Lederer  | 03:07:41    | F30-34   | 02:51:45     | 02:59:01       |
| Lauren Reasoner | 03:10:14    | F30-34   | 02:51:45     | 02:59:01       |
| Lisa Stelzner   | 02:54:11    | F35-39   | 02:54:11     | 03:01:17       |
| Lauren Matthews | 03:01:17    | F35-39   | 02:54:11     | 03:01:17       |
| Desiree Berry   | 03:05:42    | F35-39   | 02:54:11     | 03:01:17       |
| Suzy Slane      | 03:06:24    | F35-39   | 02:54:11     | 03:01:17       |
+-----------------+-------------+----------+--------------+----------------+

LEAD

LEAD (value_expression[, offset [, default_expression]])

说明

返回后续行的 value_expression 值。更改 offset 值会改变所返回的后续行;默认值是 1,表示窗口框架中的下一行。如果 offset 是 NULL 或负值,也会发生错误。

如果窗口框架中没有指定偏移量的行,则使用可选的 default_expression。此表达式必须是常量表达式,其类型必须可隐式强制转换为 value_expression 类型。如果未指定,则 default_expression 默认为 NULL。

支持的参数类型

  • value_expression 可以是表达式支持的任意返回数据类型。
  • offset 必须是非负整数字面量或参数。
  • default_expression 必须兼容值表达式类型。

返回数据类型

任意

示例

以下示例展示了 LEAD 函数的基本用法。

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  finish_time,
  division,
  LEAD(name)
    OVER (PARTITION BY division ORDER BY finish_time ASC) AS followed_by
FROM finishers;

+-----------------+-------------+----------+-----------------+
| name            | finish_time | division | followed_by     |
+-----------------+-------------+----------+-----------------+
| Carly Forte     | 03:08:58    | F25-29   | NULL            |
| Sophia Liu      | 02:51:45    | F30-34   | Nikki Leith     |
| Nikki Leith     | 02:59:01    | F30-34   | Jen Edwards     |
| Jen Edwards     | 03:06:36    | F30-34   | Meghan Lederer  |
| Meghan Lederer  | 03:07:41    | F30-34   | Lauren Reasoner |
| Lauren Reasoner | 03:10:14    | F30-34   | NULL            |
| Lisa Stelzner   | 02:54:11    | F35-39   | Lauren Matthews |
| Lauren Matthews | 03:01:17    | F35-39   | Desiree Berry   |
| Desiree Berry   | 03:05:42    | F35-39   | Suzy Slane      |
| Suzy Slane      | 03:06:24    | F35-39   | NULL            |
+-----------------+-------------+----------+-----------------+

下一个示例使用可选的 offset 参数。

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  finish_time,
  division,
  LEAD(name, 2)
    OVER (PARTITION BY division ORDER BY finish_time ASC) AS two_runners_back
FROM finishers;

+-----------------+-------------+----------+------------------+
| name            | finish_time | division | two_runners_back |
+-----------------+-------------+----------+------------------+
| Carly Forte     | 03:08:58    | F25-29   | NULL             |
| Sophia Liu      | 02:51:45    | F30-34   | Jen Edwards      |
| Nikki Leith     | 02:59:01    | F30-34   | Meghan Lederer   |
| Jen Edwards     | 03:06:36    | F30-34   | Lauren Reasoner  |
| Meghan Lederer  | 03:07:41    | F30-34   | NULL             |
| Lauren Reasoner | 03:10:14    | F30-34   | NULL             |
| Lisa Stelzner   | 02:54:11    | F35-39   | Desiree Berry    |
| Lauren Matthews | 03:01:17    | F35-39   | Suzy Slane       |
| Desiree Berry   | 03:05:42    | F35-39   | NULL             |
| Suzy Slane      | 03:06:24    | F35-39   | NULL             |
+-----------------+-------------+----------+------------------+

以下示例使用默认值替换 NULL 值。

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  finish_time,
  division,
  LEAD(name, 2, 'Nobody')
    OVER (PARTITION BY division ORDER BY finish_time ASC) AS two_runners_back
FROM finishers;

+-----------------+-------------+----------+------------------+
| name            | finish_time | division | two_runners_back |
+-----------------+-------------+----------+------------------+
| Carly Forte     | 03:08:58    | F25-29   | Nobody           |
| Sophia Liu      | 02:51:45    | F30-34   | Jen Edwards      |
| Nikki Leith     | 02:59:01    | F30-34   | Meghan Lederer   |
| Jen Edwards     | 03:06:36    | F30-34   | Lauren Reasoner  |
| Meghan Lederer  | 03:07:41    | F30-34   | Nobody           |
| Lauren Reasoner | 03:10:14    | F30-34   | Nobody           |
| Lisa Stelzner   | 02:54:11    | F35-39   | Desiree Berry    |
| Lauren Matthews | 03:01:17    | F35-39   | Suzy Slane       |
| Desiree Berry   | 03:05:42    | F35-39   | Nobody           |
| Suzy Slane      | 03:06:24    | F35-39   | Nobody           |
+-----------------+-------------+----------+------------------+

LAG

LAG (value_expression[, offset [, default_expression]])

说明

返回上一行中的 value_expression 值。更改 offset 值会改变所返回的上一行;默认值是 1,表示窗口框架中的上一行。如果 offset 是 NULL 或负值,则会发生错误。

如果窗口框架中没有指定偏移量的行,则使用可选的 default_expression。此表达式必须是常量表达式,其类型必须可隐式强制转换为 value_expression 类型。如果未指定,则 default_expression 默认为 NULL。

支持的参数类型

  • value_expression 可以是表达式支持的任意返回数据类型。
  • offset 必须是非负整数字面量或参数。
  • default_expression 必须兼容值表达式类型。

返回数据类型

任意

示例

以下示例展示了 LAG 函数的基本用法:

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  finish_time,
  division,
  LAG(name)
    OVER (PARTITION BY division ORDER BY finish_time ASC) AS preceding_runner
FROM finishers;

+-----------------+-------------+----------+------------------+
| name            | finish_time | division | preceding_runner |
+-----------------+-------------+----------+------------------+
| Carly Forte     | 03:08:58    | F25-29   | NULL             |
| Sophia Liu      | 02:51:45    | F30-34   | NULL             |
| Nikki Leith     | 02:59:01    | F30-34   | Sophia Liu       |
| Jen Edwards     | 03:06:36    | F30-34   | Nikki Leith      |
| Meghan Lederer  | 03:07:41    | F30-34   | Jen Edwards      |
| Lauren Reasoner | 03:10:14    | F30-34   | Meghan Lederer   |
| Lisa Stelzner   | 02:54:11    | F35-39   | NULL             |
| Lauren Matthews | 03:01:17    | F35-39   | Lisa Stelzner    |
| Desiree Berry   | 03:05:42    | F35-39   | Lauren Matthews  |
| Suzy Slane      | 03:06:24    | F35-39   | Desiree Berry    |
+-----------------+-------------+----------+------------------+

下一个示例使用可选的 offset 参数。

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  finish_time,
  division,
  LAG(name, 2)
    OVER (PARTITION BY division ORDER BY finish_time ASC) AS two_runners_ahead
FROM finishers;

+-----------------+-------------+----------+-------------------+
| name            | finish_time | division | two_runners_ahead |
+-----------------+-------------+----------+-------------------+
| Carly Forte     | 03:08:58    | F25-29   | NULL              |
| Sophia Liu      | 02:51:45    | F30-34   | NULL              |
| Nikki Leith     | 02:59:01    | F30-34   | NULL              |
| Jen Edwards     | 03:06:36    | F30-34   | Sophia Liu        |
| Meghan Lederer  | 03:07:41    | F30-34   | Nikki Leith       |
| Lauren Reasoner | 03:10:14    | F30-34   | Jen Edwards       |
| Lisa Stelzner   | 02:54:11    | F35-39   | NULL              |
| Lauren Matthews | 03:01:17    | F35-39   | NULL              |
| Desiree Berry   | 03:05:42    | F35-39   | Lisa Stelzner     |
| Suzy Slane      | 03:06:24    | F35-39   | Lauren Matthews   |
+-----------------+-------------+----------+-------------------+

以下示例使用默认值替换 NULL 值。

WITH finishers AS
 (SELECT 'Sophia Liu' as name,
  TIMESTAMP '2016-10-18 2:51:45' as finish_time,
  'F30-34' as division
  UNION ALL SELECT 'Lisa Stelzner', TIMESTAMP '2016-10-18 2:54:11', 'F35-39'
  UNION ALL SELECT 'Nikki Leith', TIMESTAMP '2016-10-18 2:59:01', 'F30-34'
  UNION ALL SELECT 'Lauren Matthews', TIMESTAMP '2016-10-18 3:01:17', 'F35-39'
  UNION ALL SELECT 'Desiree Berry', TIMESTAMP '2016-10-18 3:05:42', 'F35-39'
  UNION ALL SELECT 'Suzy Slane', TIMESTAMP '2016-10-18 3:06:24', 'F35-39'
  UNION ALL SELECT 'Jen Edwards', TIMESTAMP '2016-10-18 3:06:36', 'F30-34'
  UNION ALL SELECT 'Meghan Lederer', TIMESTAMP '2016-10-18 3:07:41', 'F30-34'
  UNION ALL SELECT 'Carly Forte', TIMESTAMP '2016-10-18 3:08:58', 'F25-29'
  UNION ALL SELECT 'Lauren Reasoner', TIMESTAMP '2016-10-18 3:10:14', 'F30-34')
SELECT name,
  finish_time,
  division,
  LAG(name, 2, 'Nobody')
    OVER (PARTITION BY division ORDER BY finish_time ASC) AS two_runners_ahead
FROM finishers;

+-----------------+-------------+----------+-------------------+
| name            | finish_time | division | two_runners_ahead |
+-----------------+-------------+----------+-------------------+
| Carly Forte     | 03:08:58    | F25-29   | Nobody            |
| Sophia Liu      | 02:51:45    | F30-34   | Nobody            |
| Nikki Leith     | 02:59:01    | F30-34   | Nobody            |
| Jen Edwards     | 03:06:36    | F30-34   | Sophia Liu        |
| Meghan Lederer  | 03:07:41    | F30-34   | Nikki Leith       |
| Lauren Reasoner | 03:10:14    | F30-34   | Jen Edwards       |
| Lisa Stelzner   | 02:54:11    | F35-39   | Nobody            |
| Lauren Matthews | 03:01:17    | F35-39   | Nobody            |
| Desiree Berry   | 03:05:42    | F35-39   | Lisa Stelzner     |
| Suzy Slane      | 03:06:24    | F35-39   | Lauren Matthews   |
+-----------------+-------------+----------+-------------------+

PERCENTILE_CONT

PERCENTILE_CONT (value_expression, percentile [{RESPECT | IGNORE} NULLS])

说明

使用线性插值计算 value_expression 的指定百分位值。

如果不存在 RESPECT NULLS,此函数会忽略 NULL 值。如果存在 RESPECT NULLS,则有以下情况:

  • 两个 NULL 值之间的插值返回 NULL
  • 一个 NULL 值与一个非 NULL 值之间的插值会返回非 NULL 值。

支持的参数类型

  • value_expression 是数字表达式。
  • percentile[0, 1] 范围内的一个 DOUBLE 字面量。

返回数据类型

DOUBLE

示例

以下示例计算一个值列中的某些百分位值,同时忽略 null。

SELECT
  PERCENTILE_CONT(x, 0) OVER() AS min,
  PERCENTILE_CONT(x, 0.01) OVER() AS percentile1,
  PERCENTILE_CONT(x, 0.5) OVER() AS median,
  PERCENTILE_CONT(x, 0.9) OVER() AS percentile90,
  PERCENTILE_CONT(x, 1) OVER() AS max
FROM UNNEST([0, 3, NULL, 1, 2]) AS x LIMIT 1;

+-----+-------------+--------+--------------+-----+
| min | percentile1 | median | percentile90 | max |
+-----+-------------+--------+--------------+-----+
| 0   | 0.03        | 1.5    | 2.7          | 3   |
+-----+-------------+--------+--------------+-----+

以下示例计算一个值列中的某些百分位值,同时保留 null。

SELECT
  PERCENTILE_CONT(x, 0 RESPECT NULLS) OVER() AS min,
  PERCENTILE_CONT(x, 0.01 RESPECT NULLS) OVER() AS percentile1,
  PERCENTILE_CONT(x, 0.5 RESPECT NULLS) OVER() AS median,
  PERCENTILE_CONT(x, 0.9 RESPECT NULLS) OVER() AS percentile90,
  PERCENTILE_CONT(x, 1 RESPECT NULLS) OVER() AS max
FROM UNNEST([0, 3, NULL, 1, 2]) AS x LIMIT 1;

+------+-------------+--------+--------------+-----+
| min  | percentile1 | median | percentile90 | max |
+------+-------------+--------+--------------+-----+
| NULL | 0           | 1      | 2.6          | 3   |
+------+-------------+--------+--------------+-----+

PERCENTILE_DISC

PERCENTILE_DISC (value_expression, percentile [{RESPECT | IGNORE} NULLS])

说明

计算离散 value_expression 的指定百分位值。返回值是 value_expression 的第一个经过排序的值,累积分布大于或等于给定 percentile 值。

除非存在 RESPECT NULLS,否则此函数会忽略 NULL 值。

支持的参数类型

  • value_expression 可以是任意可排序的类型。
  • percentile[0, 1] 范围内的一个 DOUBLE 字面量。

返回数据类型

ANY

示例

以下示例计算一个值列中的某些百分位值,同时忽略 null。

SELECT
  x,
  PERCENTILE_DISC(x, 0) OVER() AS min,
  PERCENTILE_DISC(x, 0.5) OVER() AS median,
  PERCENTILE_DISC(x, 1) OVER() AS max
FROM UNNEST(['c', NULL, 'b', 'a']) AS x;

+------+-----+--------+-----+
| x    | min | median | max |
+------+-----+--------+-----+
| c    | a   | b      | c   |
| NULL | a   | b      | c   |
| b    | a   | b      | c   |
| a    | a   | b      | c   |
+------+-----+--------+-----+

以下示例计算一个值列中的某些百分位值,同时保留 null。

SELECT
  x,
  PERCENTILE_DISC(x, 0 RESPECT NULLS) OVER() AS min,
  PERCENTILE_DISC(x, 0.5 RESPECT NULLS) OVER() AS median,
  PERCENTILE_DISC(x, 1 RESPECT NULLS) OVER() AS max
FROM UNNEST(['c', NULL, 'b', 'a']) AS x;

+------+------+--------+-----+
| x    | min  | median | max |
+------+------+--------+-----+
| c    | NULL | a      | c   |
| NULL | NULL | a      | c   |
| b    | NULL | a      | c   |
| a    | NULL | a      | c   |
+------+------+--------+-----+

聚合分析函数

以下部分介绍了 BigQuery 支持的聚合分析函数。如需了解分析函数的工作原理,请参阅分析函数概念。如需了解聚合分析函数的工作原理,请参阅聚合分析函数概念

BigQuery 支持将以下聚合函数作为分析函数:

OVER 子句要求:

  • PARTITION BY:可选。
  • ORDER BY:可选。如果存在 DISTINCT,则禁止。
  • window_frame_clause:可选。如果存在 DISTINCT,则禁止。

示例:

COUNT(*) OVER (ROWS UNBOUNDED PRECEDING)
SUM(DISTINCT x) OVER ()

哈希函数

FARM_FINGERPRINT

FARM_FINGERPRINT(value)

说明

使用开源 FarmHash 库中的 Fingerprint64 函数计算 STRING 或 BYTES 输入的指纹值。此函数针对特定输入的输出从不会改变。

返回类型

INT64

示例

WITH example AS (
  SELECT 1 AS x, "foo" AS y, true AS z UNION ALL
  SELECT 2 AS x, "apple" AS y, false AS z UNION ALL
  SELECT 3 AS x, "" AS y, true AS z
)
SELECT
  *,
  FARM_FINGERPRINT(CONCAT(CAST(x AS STRING), y, CAST(z AS STRING)))
    AS row_fingerprint
FROM example;
+---+-------+-------+----------------------+
| x | y     | z     | row_fingerprint      |
+---+-------+-------+----------------------+
| 1 | foo   | true  | -1541654101129638711 |
| 2 | apple | false | 2794438866806483259  |
| 3 |       | true  | -4880158226897771312 |
+---+-------+-------+----------------------+

MD5

MD5(input)

说明

使用 MD5 算法计算输入的哈希值。输入可以是 STRING 或 BYTES。字符串版本会将输入作为字节数组处理。

此函数返回 16 个字节。

返回类型

BYTES

示例

SELECT MD5("Hello World") as md5;

+-------------------------------------------------+
| md5                                             |
+-------------------------------------------------+
| \xb1\n\x8d\xb1d\xe0uA\x05\xb7\xa9\x9b\xe7.?\xe5 |
+-------------------------------------------------+

SHA1

SHA1(input)

说明

使用 SHA-1 算法计算输入的哈希值。输入可以是 STRING 或 BYTES。字符串版本会将输入作为字节数组处理。

此函数返回 20 个字节。

返回类型

BYTES

示例

SELECT SHA1("Hello World") as sha1;

+-----------------------------------------------------------+
| sha1                                                      |
+-----------------------------------------------------------+
| \nMU\xa8\xd7x\xe5\x02/\xabp\x19w\xc5\xd8@\xbb\xc4\x86\xd0 |
+-----------------------------------------------------------+

SHA256

SHA256(input)

说明

使用 SHA-256 算法计算输入的哈希值。输入可以是 STRING 或 BYTES。字符串版本会将输入作为字节数组处理。

此函数返回 32 个字节。

返回类型

BYTES

示例

SELECT SHA256("Hello World") as sha256;

SHA512

SHA512(input)

说明

使用 SHA-512 算法计算输入的哈希值。输入可以是 STRING 或 BYTES。字符串版本会将输入作为字节数组处理。

此函数返回 64 个字节。

返回类型

BYTES

示例

SELECT SHA512("Hello World") as sha512;

字符串函数

这些字符串函数作用于两种不同的值:STRING 和 BYTES 数据类型。STRING 值必须采用正确的 UTF-8 格式。

返回位置值的函数(如 STRPOS)将这些位置编码为 INT64。值 1 表示第一个字符(或字节),2 表示第二个字符(或字节),以此类推。值 0 表示无效索引。处理 STRING 类型时,返回的位置是指字符位置。

按字节逐一比较所有字符串,而不考虑 Unicode 规范相等性。

BYTE_LENGTH

BYTE_LENGTH(value)

说明

无论的类型是 STRING 还是 BYTES,都返回值的长度(以字节为单位)。

返回类型

INT64

示例

WITH example AS
  (SELECT "абвгд" AS characters, b"абвгд" AS bytes)

SELECT
  characters,
  BYTE_LENGTH(characters) AS string_example,
  bytes,
  BYTE_LENGTH(bytes) AS bytes_example
FROM example;

+------------+----------------+-------+---------------+
| characters | string_example | bytes | bytes_example |
+------------+----------------+-------+---------------+
| абвгд      | 10             | абвгд | 10            |
+------------+----------------+-------+---------------+

CHAR_LENGTH

CHAR_LENGTH(value)

说明

返回 STRING 的长度(以字符为单位)。

返回类型

INT64

示例

WITH example AS
  (SELECT "абвгд" AS characters)

SELECT
  characters,
  CHAR_LENGTH(characters) AS char_length_example
FROM example;

+------------+---------------------+
| characters | char_length_example |
+------------+---------------------+
| абвгд      |                   5 |
+------------+---------------------+

CHARACTER_LENGTH

CHARACTER_LENGTH(value)

说明

相当于 CHAR_LENGTH

返回类型

INT64

示例

WITH example AS
  (SELECT "абвгд" AS characters)

SELECT
  characters,
  CHARACTER_LENGTH(characters) AS char_length_example
FROM example;

+------------+---------------------+
| characters | char_length_example |
+------------+---------------------+
| абвгд      |                   5 |
+------------+---------------------+

CODE_POINTS_TO_BYTES

CODE_POINTS_TO_BYTES(ascii_values)

说明

获取扩展 ASCII 代码点数组(INT64 值组成的 ARRAY),并返回 BYTES。

要从 BYTES 转换为代码点数组,请参阅 TO_CODE_POINTS

返回类型

BYTES

示例

以下是使用 CODE_POINTS_TO_BYTES 的一个基本示例。

SELECT CODE_POINTS_TO_BYTES([65, 98, 67, 100]) AS bytes;

+-------+
| bytes |
+-------+
| AbCd  |
+-------+

以下示例使用 rotate-by-13 应用 (ROT13) 算法,对一个字符串进行编码。

SELECT CODE_POINTS_TO_BYTES(ARRAY_AGG(
  (SELECT
      CASE
        WHEN chr BETWEEN b'a' and b'z'
          THEN TO_CODE_POINTS(b'a')[offset(0)] +
            MOD(code+13-TO_CODE_POINTS(b'a')[offset(0)],26)
        WHEN chr BETWEEN b'A' and b'Z'
          THEN TO_CODE_POINTS(b'A')[offset(0)] +
            MOD(code+13-TO_CODE_POINTS(b'A')[offset(0)],26)
        ELSE code
      END
   FROM
     (SELECT code, CODE_POINTS_TO_BYTES([code]) chr)
  ) ORDER BY OFFSET)) AS encoded_string
FROM UNNEST(TO_CODE_POINTS(b'Test String!')) code WITH OFFSET;

+----------------+
| encoded_string |
+----------------+
| Grfg Fgevat!   |
+----------------+

CODE_POINTS_TO_STRING

CODE_POINTS_TO_STRING(value)

说明

获取一个 Unicode 代码点(INT64 类型的 ARRAY),并返回一个 STRING。

要从字符串转换为代码点数组,请参阅 TO_CODE_POINTS

返回类型

STRING

示例

下面是使用 CODE_POINTS_TO_STRING 的一个基本示例。

SELECT CODE_POINTS_TO_STRING([65, 255, 513, 1024]) AS string;

+--------+
| string |
+--------+
| AÿȁЀ   |
+--------+

以下示例计算一组单词中字母的出现频率。

WITH Words AS (
  SELECT word
  FROM UNNEST(['foo', 'bar', 'baz', 'giraffe', 'llama']) AS word
)
SELECT
  CODE_POINTS_TO_STRING([code_point]) AS letter,
  COUNT(*) AS letter_count
FROM Words,
  UNNEST(TO_CODE_POINTS(word)) AS code_point
GROUP BY 1
ORDER BY 2 DESC;

+--------+--------------+
| letter | letter_count |
+--------+--------------+
| a      | 5            |
| f      | 3            |
| r      | 2            |
| b      | 2            |
| l      | 2            |
| o      | 2            |
| g      | 1            |
| z      | 1            |
| e      | 1            |
| m      | 1            |
| i      | 1            |
+--------+--------------+

CONCAT

CONCAT(value1[, ...])

说明

将一个或多个连接成为一个结果。

返回类型

STRING 或 BYTES

示例

With Employees AS
  (SELECT
    "John" AS first_name,
    "Doe" AS last_name
  UNION ALL
  SELECT
    "Jane" AS first_name,
    "Smith" AS last_name
  UNION ALL
  SELECT
    "Joe" AS first_name,
    "Jackson" AS last_name)

SELECT
  CONCAT(first_name, " ", last_name)
  AS full_name
FROM Employees;

+---------------------+
| full_name           |
+---------------------+
| John Doe            |
| Jane Smith          |
| Joe Jackson         |
+---------------------+

ENDS_WITH

ENDS_WITH(value1, value2)

说明

获取两个。如果第二个值是第一个值的后缀,则返回 TRUE。

返回类型

BOOL

示例

WITH items AS
  (SELECT "apple" as item
  UNION ALL
  SELECT "banana" as item
  UNION ALL
  SELECT "orange" as item)

SELECT
  ENDS_WITH(item, "e") as example
FROM items;

+---------+
| example |
+---------+
|    True |
|   False |
|    True |
+---------+

FORMAT

BigQuery 支持用于格式化字符串的 FORMAT() 函数。此函数类似于 C 语言中的 printf 函数。它会根据一个包含零个或多个格式说明符的格式化字符串,以及一个包含与格式说明符匹配的额外参数的可变长度列表来生成一个 STRING。以下是一些示例:

说明 语句 结果
简单整数 format("%d", 10) 10
左侧填充了空白的整数 format("|%10d|", 11) |           11|
左侧填充了数字零的整数 format("+%010d+", 12) +0000000012+
用英文逗号分隔的整数 format("%d", 10) 123,456,789
STRING format("-%s-", 'abcd efg') -abcd efg-
FLOAT64 format("%f %E", 1.1, 2.2) 1.100000 2.200000E+00
DATE format("%t", date "2015-09-01") 2015-09-01
TIMESTAMP format("%t", timestamp "2015-09-01 12:34:56 America/Los_Angeles") 2015‑09‑01 19:34:56+00

FORMAT() 函数不会为所有类型和值提供完全可自定义的格式,也不支持设置对语言区域敏感的格式。

如果某个类型必须使用自定义格式设置,则您必须首先使用特定类型的格式化函数(例如 FORMAT_DATE()FORMAT_TIMESTAMP())对其进行格式化。例如:

FORMAT("date: %s!", FORMAT_DATE("%B %d, %Y", date '2015-01-02'));

返回

date: January 02, 2015!

语法

FORMAT() 语法获取一个格式化字符串和可变长度参数列表,并生成一个 STRING 结果:

FORMAT(<format_string>, ...)

<format_string> 表达式可以包含零个或多个格式说明符。每个格式说明符均由 % 符号引入,必须映射到一个或多个其余参数。除非存在 * 说明符,否则在大多数情况下,这都是一对一映射。例如,%.*i 映射到两个参数:一个长度参数和一个带符号整数参数。如果与格式说明符相关的参数数量与参数数量不同,则会出现错误。

支持的格式说明符

FORMAT() 函数格式说明符遵循以下原型:

%[flags][width][.precision]specifier

下标中标识了支持的格式说明符。来自 printf() 函数的扩展用斜体表示。

说明符 说明 示例 类型
di 十进制整数 392 INT64
o 八进制 610
INT64*
x 十六进制整数 7fa
INT64*
X 十六进制整数(大写) 7FA
INT64*
f 十进制浮点数,小写 392.65
inf
NaN

NUMERIC
FLOAT64
F 十进制浮点数,大写 392.65
inf
NaN

NUMERIC
FLOAT64
e 科学记数法(尾数/指数),小写 3.9265e+2
inf
NaN

NUMERIC
FLOAT64
E 科学记数法(尾数/指数),大写 3.9265E+2
inf
NAN
NUMERIC
FLOAT64
g 使用最短的表示方式,%e 或 %f 392.65
FLOAT64
G 使用最短的表示方式,%E 或 %F 392.65
FLOAT64
s 字符串 sample STRING
t 返回表示值的可打印字符串。通常看起来类似于将参数类型转换为 STRING。请参阅下面的 %t 部分 示例
2014‑01‑01
<任意>
T 生成一个字符串,这是一个类型与值类型相似的有效 BigQuery 常量(可能宽度更大,也可能是字符串)。 请参阅下面的 %T 部分 'sample'
b'bytes sample'
1234
2.3
date '2014‑01‑01'

<任意>
% '%%' 会生成一个 '%' % 不适用

*如果使用了负值,则说明符 o、x 和 X 会抛出错误。

格式说明符可以选择性地在说明符原型中包含上面所述的子说明符。

这些子说明符必须符合以下规范。

标记
标记 说明
- 在给定字段宽度内左对齐;默认设置为右对齐(请参阅宽度子说明符)
+ 强制在结果前面加上加号或减号(+-),即便对于正数也是如此。默认情况下,仅有负数带 - 符号前缀
<空格> 如果不会写入任何符号,则在值前插入一个空格
# 配合 o、x 或 X 说明符使用。对于 0 以外的值,在值前分别加上 0、0x 或 0X 前缀
0 在指定填充时,在左侧填充数字零 (0),而非填充空格(参见宽度子说明符)
'

使用适当的分组字符格式化整数。例如:

  • FORMAT("%'d", 12345678) 返回 12,345,678
  • FORMAT("%'x", 12345678) 返回 bc:614e
  • FORMAT("%'o", 55555) 返回 15,4403
  • 此标记仅与十进制、十六进制和八进制值相关。

标记可以按照任意顺序指定。标记重复不属于错误。在标记与某些元素类型不相关时,标记会被忽略。

宽度
宽度 说明
<数字> 要打印的最小字符数。如果要打印的值比这个数字短,结果将用空格填充。即便结果较大,该值也不会被截断
* 宽度并非在格式字符串中指定,而是作为一个额外的整数值参数指定,置于必须格式化的参数之前
精度
精度 说明
.<数字> 对于正数说明符(d、i、o、u、x、X):精度指定要写入的最小位数。如果要写入的值比这个数字短,则用尾随零填充结果。即便结果较长,该值也不会被截断。精度为 0 则表示不会为值 0 写入字符。对于 a、A、e、E、f 和 F 说明符,这表示小数点后要打印的位数(默认情况下,这是 6)
.* 精度并非在格式字符串中指定,而是作为一个额外的整数值参数指定,置于必须格式化的参数之前

%t 和 %T 行为

%t%T 格式说明符会为所有类型定义。宽度、精度和标记的行为方式与其在 %s 中的行为方式相同:width 是最小宽度,STRING 将填充到此宽度,precision 是要显示的最大内容宽度,STRING 将截断到该宽度,之后再填充到合适的宽度。

%t 始终旨在用作值的可读形式。

%T 始终是类似类型的有效 SQL 字面量,例如宽度较大的数字类型。除在非有限浮点值的特殊情况下之外,该字面量不包含类型转换或类型名称。

STRING 格式设置如下:

类型 %t %T
任意类型的 NULL NULL NULL
INT64
123 123
NUMERIC 123.0(始终带有 .0) NUMERIC "123.0"
FLOAT64 123.0(始终带有 .0)
123e+10
inf
-inf
NaN
123.0(始终带有 .0)
123e+10
CAST("inf" AS <type>)
CAST("-inf" AS <type>)
CAST("nan" AS <type>)


STRING 不带引号的字符串值 带引号的字符串字面量
BYTES 不带引号的转义字节
例如:abc\x01\x02
带引号的字节字面量
例如:b"abc\x01\x02"
DATE 2011-02-03 DATE "2011-02-03"
TIMESTAMP 2011-02-03 04:05:06+00 TIMESTAMP "2011-02-03 04:05:06+00"
ARRAY [值, 值, ...]
其中的值使用 %t 设置格式
[值, 值, ...]
其中的值使用 %T 设置格式
STRUCT (值, 值, ...)
其中的字段使用 %t 设置格式
(值, 值, ...)
其中的字段使用 %T 设置格式

特殊情况:
零个字段:STRUCT()
一个字段:STRUCT(value)

错误条件

如果格式说明符无效,或者与相关参数类型不兼容,或者提供了错误的数字或参数,则会引发错误。例如,以下 <format_string> 表达式无效:

FORMAT('%s', 1)
FORMAT('%')

NULL 参数处理

NULL 格式字符串是一个 NULL 输出 STRING。在本例中,其他任何参数都会被忽略。

如果存在 NULL 参数,此函数通常会产生一个 NULL 值。例如,FORMAT('%i', <NULL expression>) 会生成一个 NULL STRING 作为输出。

但也有一些例外情况,如果格式说明符是 %t 或 %T(两者均生成有效匹配 CAST 和字面量值语义的 STRING),则 NULL 值会在结果 STRING 中生成“NULL”(不带引号)。例如,如下函数:

FORMAT('00-%t-00', <NULL expression>);

返回

00-NULL-00

其他语义规则

FLOAT64 值可以是 +/-infNaN。在参数具有其中某个值时,格式说明符 %f%F%e%E%g%G%t 的结果是可能是 inf-infnan(或者相同的大写形式,根据相应条件)。这与 BigQuery 将这些值的类型转换为 STRING 的方式一致。对于 %T,BigQuery 会为没有使用非字符串字面量表示形式的 FLOAT64 值返回带引号的字符串。

FROM_BASE32

FROM_BASE32(string_expr)

说明

将 base32 编码的输入 string_expr 转换为 BYTES 格式。要将 BYTES 转换为 base32 编码的 STRING,请使用 TO_BASE32

返回类型

BYTES

示例

SELECT FROM_BASE32('MFRGGZDF74======') AS byte_data;

+-----------+
| byte_data |
+-----------+
| abcde\xff |
+-----------+

FROM_BASE64

FROM_BASE64(string_expr)

说明

将 base64 编码的输入 string_expr 转换为 BYTES 格式。要将 BYTES 转换为 base64 编码的 STRING,请使用 TO_BASE64

返回类型

BYTES

示例

SELECT FROM_BASE64('3q2+7w==') AS byte_data;

+------------------+
| byte_data        |
+------------------+
| \xde\xad\xbe\xef |
+------------------+

FROM_HEX

FROM_HEX(string)

说明

将十六进制编码的 STRING 转换为 BYTES 格式。如果输入 STRING 包含 (0..9, A..F, a..f) 范围以外的字符,则会返回错误。字符不区分大小写。如果输入 STRING 包含奇数个字符,则该函数的作用就像是输入中有一个额外的前导 0。要将 BYTES 转换为十六进制编码的 STRING,请使用 TO_HEX

返回类型

BYTES

示例

WITH Input AS (
  SELECT '00010203aaeeefff' AS hex_str UNION ALL
  SELECT '0AF' UNION ALL
  SELECT '666f6f626172'
)
SELECT hex_str, FROM_HEX(hex_str) AS bytes_str
FROM Input;
+------------------+----------------------------------+
| hex_str          | bytes_str                        |
+------------------+----------------------------------+
| 0AF              | \x00\xaf                         |
| 00010203aaeeefff | \x00\x01\x02\x03\xaa\xee\xef\xff |
| 666f6f626172     | foobar                           |
+------------------+----------------------------------+

LENGTH

LENGTH(value)

说明

返回的长度。STRING 参数的返回值以字符为单位,BYTES 参数的返回值以字节为单位。

返回类型

INT64

示例

WITH example AS
  (SELECT "абвгд" AS characters)

SELECT
  characters,
  LENGTH(characters) AS string_example,
  LENGTH(CAST(characters AS BYTES)) AS bytes_example
FROM example;

+------------+----------------+---------------+
| characters | string_example | bytes_example |
+------------+----------------+---------------+
| абвгд      |              5 |            10 |
+------------+----------------+---------------+

LPAD

LPAD(original_value, return_length[, pattern])

说明

返回由附带前缀 patternoriginal_value 组成的return_length 是一个 INT64,指定了返回值的长度。如果 original_value 是 BYTES,return_length 就是字节数。如果 original_value 是 STRING,return_length 就是字符数。

pattern 的默认值是一个空格。

original_valuepattern 必须采用相同的数据类型。

如果 return_length 小于或等于 original_value 长度,此函数会返回 original_value 值,并截断到 return_length 值。例如,LPAD("hello world", 7); 会返回 "hello w"

如果 original_valuereturn_lengthpattern 是 NULL,此函数会返回 NULL。

在以下情况下,此函数会返回错误:

  • return_length 为负
  • pattern 为空

返回类型

STRING 或 BYTES

示例

SELECT t, len, FORMAT("%T", LPAD(t, len)) AS LPAD FROM UNNEST([
  STRUCT('abc' AS t, 5 AS len),
  ('abc', 2),
  ('例子', 4)
]);
t len LPAD
abc 5 "  abc"
abc 2 "ab"
例子 4 "  例子"
SELECT t, len, pattern, FORMAT("%T", LPAD(t, len, pattern)) AS LPAD FROM UNNEST([
  STRUCT('abc' AS t, 8 AS len, 'def' AS pattern),
  ('abc', 5, '-'),
  ('例子', 5, '中文')
]);
t len pattern LPAD
abc 8 def "defdeabc"
abc 5 - "--abc"
例子 5 中文 "中文中例子"
SELECT FORMAT("%T", t) AS t, len, FORMAT("%T", LPAD(t, len)) AS LPAD FROM UNNEST([
  STRUCT(b'abc' AS t, 5 AS len),
  (b'abc', 2),
  (b'\xab\xcd\xef', 4)
]);
t len LPAD
b"abc" 5 b"  abc"
b"abc" 2 b"ab"
b"\xab\xcd\xef" 4 b" \xab\xcd\xef"
SELECT
  FORMAT("%T", t) AS t,
  len,
  FORMAT("%T", pattern) AS pattern,
  FORMAT("%T", LPAD(t, len, pattern)) AS LPAD
FROM UNNEST([
  STRUCT(b'abc' AS t, 8 AS len, b'def' AS pattern),
  (b'abc', 5, b'-'),
  (b'\xab\xcd\xef', 5, b'\x00')
]);
t len pattern LPAD
b"abc" 8 b"def" b"defdeabc"
b"abc" 5 b"-" b"--abc"
b"\xab\xcd\xef" 5 b"\x00" b"\x00\x00\xab\xcd\xef"

LOWER

LOWER(value)

说明

对于 STRING 参数,返回所有字母字符均为小写的原始字符串。根据 Unicode 字符数据库在小写与大写之间进行映射,不考虑特定语言的映射。

对于 BYTES 参数,参数被视为 ASCII 文本且大于 127 的所有字节保持不变。

返回类型

STRING 或 BYTES

示例

WITH items AS
  (SELECT
    "FOO" as item
  UNION ALL
  SELECT
    "BAR" as item
  UNION ALL
  SELECT
    "BAZ" as item)

SELECT
  LOWER(item) AS example
FROM items;

+---------+
| example |
+---------+
| foo     |
| bar     |
| baz     |
+---------+

LTRIM

LTRIM(value1[, value2])

说明

相当于 TRIM,但仅移除前导字符。

返回类型

STRING 或 BYTES

示例

WITH items AS
  (SELECT "   apple   " as item
  UNION ALL
  SELECT "   banana   " as item
  UNION ALL
  SELECT "   orange   " as item)

SELECT
  CONCAT("#", LTRIM(item), "#") as example
FROM items;

+-------------+
| example     |
+-------------+
| #apple   #  |
| #banana   # |
| #orange   # |
+-------------+

WITH items AS
  (SELECT "***apple***" as item
  UNION ALL
  SELECT "***banana***" as item
  UNION ALL
  SELECT "***orange***" as item)

SELECT
  LTRIM(item, "*") as example
FROM items;

+-----------+
| example   |
+-----------+
| apple***  |
| banana*** |
| orange*** |
+-----------+

WITH items AS
  (SELECT "xxxapplexxx" as item
  UNION ALL
  SELECT "yyybananayyy" as item
  UNION ALL
  SELECT "zzzorangezzz" as item
  UNION ALL
  SELECT "xyzpearxyz" as item)

SELECT
  LTRIM(item, "xyz") as example
FROM items;

+-----------+
| example   |
+-----------+
| applexxx  |
| bananayyy |
| orangezzz |
| pearxyz   |
+-----------+

NORMALIZE

NORMALIZE(value[, normalization_mode])

说明

获取一个 STRING 类型的 value,并以标准化字符串的形式将其返回。

标准化用于确保两个字符串是等同的。标准化往往用于两个字符串在屏幕上显示相同,但具有不同的 Unicode 代码点的情况。

NORMALIZE 支持四种可选的标准化模式:

名称 说明
NFC 标准化形式的规范组成 按规范相等性分解和重新组合字符。
NFKC 规范化形式的兼容性组成 按兼容性分解字符,然后按规范相等性重新组合字符。
NFD 标准化形式的规范分解 按规范相等性分解字符,并且按特定顺序对排列多个组合字符。
NFKD 规范化形式的兼容性分解 按兼容性分解字符,并且按特定顺序对排列多个组合字符。

默认标准化模式是 NFC

返回类型

STRING

示例

SELECT a, b, a = b as normalized
FROM (SELECT NORMALIZE('\u00ea') as a, NORMALIZE('\u0065\u0302') as b)
AS normalize_example;

+---+---+------------+
| a | b | normalized |
+---+---+------------+
| ê | ê | true       |
+---+---+------------+

以下示例标准化不同的空格字符。

WITH EquivalentNames AS (
  SELECT name
  FROM UNNEST([
      'Jane\u2004Doe',
      'John\u2004Smith',
      'Jane\u2005Doe',
      'Jane\u2006Doe',
      'John Smith']) AS name
)
SELECT
  NORMALIZE(name, NFKC) AS normalized_name,
  COUNT(*) AS name_count
FROM EquivalentNames
GROUP BY 1;

+-----------------+------------+
| normalized_name | name_count |
+-----------------+------------+
| John Smith      | 2          |
| Jane Doe        | 3          |
+-----------------+------------+

NORMALIZE_AND_CASEFOLD

NORMALIZE_AND_CASEFOLD(value[, normalization_mode])

说明

获取一个 STRING 类型的 value,并执行与 NORMALIZE 相同的操作,以及为不区分大小写的运算执行大写转换

NORMALIZE_AND_CASEFOLD 支持四种可选的标准化模式:

名称 说明
NFC 标准化形式的规范组成 按规范相等性分解和重新组合字符。
NFKC 规范化形式的兼容性组成 按兼容性分解字符,然后按规范相等性重新组合字符。
NFD 标准化形式的规范分解 按规范相等性分解字符,并且按特定顺序对排列多个组合字符。
NFKD 规范化形式的兼容性分解 按兼容性分解字符,并且按特定顺序对排列多个组合字符。

默认标准化模式是 NFC

返回类型

STRING

示例

WITH Strings AS (
  SELECT '\u2168' AS a, 'IX' AS b UNION ALL
  SELECT '\u0041\u030A', '\u00C5'
)
SELECT a, b,
  NORMALIZE_AND_CASEFOLD(a, NFD)=NORMALIZE_AND_CASEFOLD(b, NFD) AS nfd,
  NORMALIZE_AND_CASEFOLD(a, NFC)=NORMALIZE_AND_CASEFOLD(b, NFC) AS nfc,
  NORMALIZE_AND_CASEFOLD(a, NFKD)=NORMALIZE_AND_CASEFOLD(b, NFKD) AS nkfd,
  NORMALIZE_AND_CASEFOLD(a, NFKC)=NORMALIZE_AND_CASEFOLD(b, NFKC) AS nkfc
FROM Strings;

+---+----+-------+-------+------+------+
| a | b  | nfd   | nfc   | nkfd | nkfc |
+---+----+-------+-------+------+------+
| Ⅸ | IX | false | false | true | true |
| Å | Å  | true  | true  | true | true |
+---+----+-------+-------+------+------+

REGEXP_CONTAINS

REGEXP_CONTAINS(value, regex)

说明

如果 value 与正则表达式 regex 部分匹配,则返回 TRUE。

如果 regex 参数无效,则函数返回一个错误。

您可使用 ^(文本开头)和 $(文本结尾)搜索完整匹配。由于存在正则表达式运算符优先级,因此最好在 ^$ 之间的内容两边使用括号。

注意:BigQuery 通过 re2 库提供正则表达式支持;请参阅该文档,了解正则表达式的语法。

返回类型

BOOL

示例

SELECT
  email,
  REGEXP_CONTAINS(email, r"@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+") AS is_valid
FROM
  (SELECT
    ["foo@example.com", "bar@example.org", "www.example.net"]
    AS addresses),
  UNNEST(addresses) AS email;

+-----------------+----------+
| email           | is_valid |
+-----------------+----------+
| foo@example.com | true     |
| bar@example.org | true     |
| www.example.net | false    |
+-----------------+----------+

# Performs a full match, using ^ and $. Due to regular expression operator
# precedence, it is good practice to use parentheses around everything between ^
# and $.
SELECT
  email,
  REGEXP_CONTAINS(email, r"^([\w.+-]+@foo\.com|[\w.+-]+@bar\.org)$")
    AS valid_email_address,
  REGEXP_CONTAINS(email, r"^[\w.+-]+@foo\.com|[\w.+-]+@bar\.org$")
    AS without_parentheses
FROM
  (SELECT
    ["a@foo.com", "a@foo.computer", "b@bar.org", "!b@bar.org", "c@buz.net"]
    AS addresses),
  UNNEST(addresses) AS email;

+----------------+---------------------+---------------------+
| email          | valid_email_address | without_parentheses |
+----------------+---------------------+---------------------+
| a@foo.com      | true                | true                |
| a@foo.computer | false               | true                |
| b@bar.org      | true                | true                |
| !b@bar.org     | false               | true                |
| c@buz.net      | false               | false               |
+----------------+---------------------+---------------------+

REGEXP_EXTRACT

REGEXP_EXTRACT(value, regex)

说明

返回 value 中与正则表达式 regex 匹配的第一个子字符串。如果不存在匹配项,则返回 NULL

如果正则表达式包含捕获组,则函数返回该捕获组匹配的子字符串。如果表达式不包含捕获组,则函数返回整个匹配的子字符串。

出现以下情况时返回一个错误:

  • 正则表达式无效
  • 正则表达式具有多个捕获组

注意:BigQuery 通过 re2 库提供正则表达式支持;请参阅该文档,了解正则表达式的语法。

返回类型

STRING 或 BYTES

示例

WITH email_addresses AS
  (SELECT "foo@example.com" as email
  UNION ALL
  SELECT "bar@example.org" as email
  UNION ALL
  SELECT "baz@example.net" as email)

SELECT
  REGEXP_EXTRACT(email, r"^[a-zA-Z0-9_.+-]+")
  AS user_name
FROM email_addresses;

+-----------+
| user_name |
+-----------+
| foo       |
| bar       |
| baz       |
+-----------+

WITH email_addresses AS
  (SELECT "foo@example.com" as email
  UNION ALL
  SELECT "bar@example.org" as email
  UNION ALL
  SELECT "baz@example.net" as email)

SELECT
  REGEXP_EXTRACT(email, r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.([a-zA-Z0-9-.]+$)")
  AS top_level_domain
FROM email_addresses;

+------------------+
| top_level_domain |
+------------------+
| com              |
| org              |
| net              |
+------------------+

REGEXP_EXTRACT_ALL

REGEXP_EXTRACT_ALL(value, regex)

说明

返回 value 中与正则表达式 regex 匹配的所有子字符串的数组。

REGEXP_EXTRACT_ALL 函数仅返回非重叠的匹配项。例如,使用此函数从 ana 中提取 banana 时仅返回一个子字符串,而不是两个。

注意:BigQuery 通过 re2 库提供正则表达式支持;请参阅该文档,了解正则表达式的语法。

返回类型

STRING 或 BYTES 的 ARRAY 类型

示例

WITH code_markdown AS
  (SELECT "Try `function(x)` or `function(y)`" as code)

SELECT
  REGEXP_EXTRACT_ALL(code, "`(.+?)`") AS example
FROM code_markdown;

+----------------------------+
| example                    |
+----------------------------+
| [function(x), function(y)] |
+----------------------------+

REGEXP_REPLACE

REGEXP_REPLACE(value, regex, replacement)

说明

value 中与正则表达式 regex 匹配的所有子字符串都替换为 replacement 时,返回 STRING。

您可以在 replacement 参数中使用通过反斜杠转义的数字(\1 至 \9)来插入与 regex 模式中用括号括起来的对应组匹配的文本。“\0”可用于引用整个匹配的文本。

注意:要在正则表达式中添加反斜杠,必须先对其进行转义。例如,SELECT REGEXP_REPLACE("abc", "b(.)", "X\\1"); 返回 aXc

REGEXP_REPLACE 函数仅替换非重叠的匹配项。例如,替换 banana 结果中的 ana 时仅替换一处,而不是两处。

如果 regex 参数不是有效的正则表达式,则此函数返回一个错误。

注意:BigQuery 通过 re2 库提供正则表达式支持;请参阅该文档,了解正则表达式的语法。

返回类型

STRING 或 BYTES

示例

WITH markdown AS
  (SELECT "# Heading" as heading
  UNION ALL
  SELECT "# Another heading" as heading)

SELECT
  REGEXP_REPLACE(heading, r"^# ([a-zA-Z0-9\s]+$)", "<h1>\\1</h1>")
  AS html
FROM markdown;

+--------------------------+
| html                     |
+--------------------------+
| <h1>Heading</h1>         |
| <h1>Another heading</h1> |
+--------------------------+

REPLACE

REPLACE(original_value, from_value, to_value)

说明

from_value 中出现的 to_value 全部替换为 original_value。如果 from_value 为空,则不执行替换。

返回类型

STRING 或 BYTES

示例

WITH desserts AS
  (SELECT "apple pie" as dessert
  UNION ALL
  SELECT "blackberry pie" as dessert
  UNION ALL
  SELECT "cherry pie" as dessert)

SELECT
  REPLACE (dessert, "pie", "cobbler") as example
FROM desserts;

+--------------------+
| example            |
+--------------------+
| apple cobbler      |
| blackberry cobbler |
| cherry cobbler     |
+--------------------+

REPEAT

REPEAT(original_value, repetitions)

说明

返回由重复的 original_value 组成的repetitions 参数指定 original_value 的重复次数。如果 original_valuerepetitions 为 NULL,则返回 NULL。

如果 repetitions 值为负,该函数会返回错误。

返回类型

STRING 或 BYTES

示例

SELECT t, n, REPEAT(t, n) AS REPEAT FROM UNNEST([
  STRUCT('abc' AS t, 3 AS n),
  ('例子', 2),
  ('abc', null),
  (null, 3)
]);
t n REPEAT
abc 3 abcabcabc
例子 2 例子例子
abc NULL NULL
NULL 3 NULL

REVERSE

REVERSE(value)

说明

返回输入 STRING 或 BYTES 的反转值。

返回类型

STRING 或 BYTES

示例

WITH example AS (
  SELECT "foo" AS sample_string, b"bar" AS sample_bytes UNION ALL
  SELECT "абвгд" AS sample_string, b"123" AS sample_bytes
)
SELECT
  sample_string,
  REVERSE(sample_string) AS reverse_string,
  sample_bytes,
  REVERSE(sample_bytes) AS reverse_bytes
FROM example;

+---------------+----------------+--------------+---------------+
| sample_string | reverse_string | sample_bytes | reverse_bytes |
+---------------+----------------+--------------+---------------+
| foo           | oof            | bar          | rab           |
| абвгд         | дгвба          | 123          | 321           |
+---------------+----------------+--------------+---------------+

RPAD

RPAD(original_value, return_length[, pattern])

说明

返回由附带前缀 patternoriginal_value 组成的return_length 是一个 INT64,指定了返回值的长度。如果 original_value 是 BYTES,return_length 就是字节数。如果 original_value 是 STRING,return_length 就是字符数。

pattern 的默认值是一个空格。

original_valuepattern 必须采用相同的数据类型。

如果 return_length 小于或等于 original_value 长度,此函数会返回 original_value 值,并截断到 return_length 值。例如,RPAD("hello world", 7); 会返回 "hello w"

如果 original_valuereturn_lengthpattern 是 NULL,此函数会返回 NULL。

在以下情况下,此函数会返回错误:

  • return_length 为负
  • pattern 为空

返回类型

STRING 或 BYTES

示例

SELECT t, len, FORMAT("%T", RPAD(t, len)) AS RPAD FROM UNNEST([
  STRUCT('abc' AS t, 5 AS len),
  ('abc', 2),
  ('例子', 4)
]);
t len RPAD
abc 5 "abc  "
abc 2 "ab"
例子 4 "例子  "
SELECT t, len, pattern, FORMAT("%T", RPAD(t, len, pattern)) AS RPAD FROM UNNEST([
  STRUCT('abc' AS t, 8 AS len, 'def' AS pattern),
  ('abc', 5, '-'),
  ('例子', 5, '中文')
]);
t len pattern RPAD
abc 8 def "abcdefde"
abc 5 - "abc--"
例子 5 中文 "例子中文中"
SELECT FORMAT("%T", t) AS t, len, FORMAT("%T", RPAD(t, len)) AS RPAD FROM UNNEST([
  STRUCT(b'abc' AS t, 5 AS len),
  (b'abc', 2),
  (b'\xab\xcd\xef', 4)
]);
t len RPAD
b"abc" 5 b"abc  "
b"abc" 2 b"ab"
b"\xab\xcd\xef" 4 b"\xab\xcd\xef "
SELECT
  FORMAT("%T", t) AS t,
  len,
  FORMAT("%T", pattern) AS pattern,
  FORMAT("%T", RPAD(t, len, pattern)) AS RPAD
FROM UNNEST([
  STRUCT(b'abc' AS t, 8 AS len, b'def' AS pattern),
  (b'abc', 5, b'-'),
  (b'\xab\xcd\xef', 5, b'\x00')
]);
t len pattern RPAD
b"abc" 8 b"def" b"abcdefde"
b"abc" 5 b"-" b"abc--"
b"\xab\xcd\xef" 5 b"\x00" b"\xab\xcd\xef\x00\x00"

RTRIM

RTRIM(value1[, value2])

说明

相当于 TRIM,但仅移除尾随字符。

返回类型

STRING 或 BYTES

示例

WITH items AS
  (SELECT "***apple***" as item
  UNION ALL
  SELECT "***banana***" as item
  UNION ALL
  SELECT "***orange***" as item)

SELECT
  RTRIM(item, "*") as example
FROM items;

+-----------+
| example   |
+-----------+
| ***apple  |
| ***banana |
| ***orange |
+-----------+

WITH items AS
  (SELECT "applexxx" as item
  UNION ALL
  SELECT "bananayyy" as item
  UNION ALL
  SELECT "orangezzz" as item
  UNION ALL
  SELECT "pearxyz" as item)

SELECT
  RTRIM(item, "xyz") as example
FROM items;

+---------+
| example |
+---------+
| apple   |
| banana  |
| orange  |
| pear    |
+---------+

SAFE_CONVERT_BYTES_TO_STRING

SAFE_CONVERT_BYTES_TO_STRING(value)

说明

将字节序列转换为字符串。任何无效的 UTF-8 字符都会被 Unicode 替换字符 U+FFFD 所替代。

返回类型

STRING

示例

以下语句会返回 Unicode 替换字符 �。

SELECT SAFE_CONVERT_BYTES_TO_STRING(b'\xc2') as safe_convert;

SPLIT

SPLIT(value[, delimiter])

说明

使用 delimiter 参数拆分 value

对于 STRING,默认分隔符是逗号 ,

对于 BYTES,您必须指定一个分隔符。

对于 STRING 值,拆分空的分隔符会生成一个 UTF-8 字符数组,对于 BYTES 值则会生成一个 BYTES 数组。

拆分空 STRING 会返回包含一个空 STRING 的 ARRAY。

返回类型

由 STRING 类型组成的 ARRAY 或由 BYTES 类型组成的 ARRAY

示例

WITH letters AS
  (SELECT "a b c d" as letter_group
  UNION ALL
  SELECT "e f g h" as letter_group
  UNION ALL
  SELECT "i j k l" as letter_group)

SELECT SPLIT(letter_group, " ") as example
FROM letters;

+----------------------+
| example              |
+----------------------+
| [a, b, c, d]         |
| [e, f, g, h]         |
| [i, j, k, l]         |
+----------------------+

STARTS_WITH

STARTS_WITH(value1, value2)

说明

获取两个。如果第二个值是第一个值的前缀,则返回 TRUE。

返回类型

BOOL

示例

WITH items AS
  (SELECT "foo" as item
  UNION ALL
  SELECT "bar" as item
  UNION ALL
  SELECT "baz" as item)

SELECT
  STARTS_WITH(item, "b") as example
FROM items;

+---------+
| example |
+---------+
|   False |
|    True |
|    True |
+---------+

STRPOS

STRPOS(string, substring)

说明

返回 string 中第一次出现 substring 处的索引(以 1 开头)。如果找不到 substring,则返回 0

返回类型

INT64

示例

WITH email_addresses AS
  (SELECT
    "foo@example.com" AS email_address
  UNION ALL
  SELECT
    "foobar@example.com" AS email_address
  UNION ALL
  SELECT
    "foobarbaz@example.com" AS email_address
  UNION ALL
  SELECT
    "quxexample.com" AS email_address)

SELECT
  STRPOS(email_address, "@") AS example
FROM email_addresses;

+---------+
| example |
+---------+
|       4 |
|       7 |
|      10 |
|       0 |
+---------+

SUBSTR

SUBSTR(value, position[, length])

说明

返回所提供的的子字符串。position 参数是一个指定子字符串开始位置的整数,其中 position = 1 表示第一个字符或字节。length 参数是 STRING 参数的最大字符数或 BYTES 参数的最大字节数。

如果 position 为负,则函数从 value 末尾开始计数,其中 -1 表示最后一个字符。

如果 position 表示不在 STRING 左端(position = 0 或 position < -LENGTH(value))的一个位置,则函数从 position = 1 处开始计数。如果 length 超出了 value 的长度,则返回的字符数少于 length

如果 length 小于 0,则函数返回一个错误。

返回类型

STRING 或 BYTES

示例

WITH items AS
  (SELECT "apple" as item
  UNION ALL
  SELECT "banana" as item
  UNION ALL
  SELECT "orange" as item)

SELECT
  SUBSTR(item, 2) as example
FROM items;

+---------+
| example |
+---------+
| pple    |
| anana   |
| range   |
+---------+

WITH items AS
  (SELECT "apple" as item
  UNION ALL
  SELECT "banana" as item
  UNION ALL
  SELECT "orange" as item)

SELECT
  SUBSTR(item, 2, 2) as example
FROM items;

+---------+
| example |
+---------+
| pp      |
| an      |
| ra      |
+---------+

WITH items AS
  (SELECT "apple" as item
  UNION ALL
  SELECT "banana" as item
  UNION ALL
  SELECT "orange" as item)

SELECT
  SUBSTR(item, -2) as example
FROM items;

+---------+
| example |
+---------+
| le      |
| na      |
| ge      |
+---------+

TO_BASE32

TO_BASE32(bytes_expr)

说明

将 BYTES 序列转换为 base32 编码的 STRING。要将 base32 编码的 STRING 转换为 BYTES,可使用 FROM_BASE32

返回类型

STRING

示例

SELECT TO_BASE32(b'abcde\xFF') AS base32_string;

+------------------+
| base32_string    |
+------------------+
| MFRGGZDF74====== |
+------------------+

TO_BASE64

TO_BASE64(bytes_expr)

说明

将 BYTES 序列转换为 base64 编码的 STRING。要将 base64 编码的 STRING 转换为 BYTES,可使用 FROM_BASE64

返回类型

STRING

示例

SELECT TO_BASE64(b'\xde\xad\xbe\xef') AS base64_string;

+---------------+
| base64_string |
+---------------+
| 3q2+7w==      |
+---------------+

TO_CODE_POINTS

TO_CODE_POINTS(value)

说明

获取一个并返回 INT64 数组。

  • 如果 value 是 STRING,所返回的数组中的每个元素都代表一个代码点。每个代码点都位于 [0, 0xD7FF] 和 [0xE000, 0x10FFFF] 的范围内。
  • 如果 value 是 BYTES,数组中的每个元素都是 [0, 255] 范围内的一个扩展 ASCII 字符值。

要将代码点数组转换为 STRING 或 BYTES,请参阅 CODE_POINTS_TO_STRINGCODE_POINTS_TO_BYTES

返回类型

INT64 类型的 ARRAY

示例

以下示例为一个单词数组中的每个元素获取代码点。

SELECT word, TO_CODE_POINTS(word) AS code_points
FROM UNNEST(['foo', 'bar', 'baz', 'giraffe', 'llama']) AS word;

+---------+------------------------------------+
| word    | code_points                        |
+---------+------------------------------------+
| foo     | [102, 111, 111]                    |
| bar     | [98, 97, 114]                      |
| baz     | [98, 97, 122]                      |
| giraffe | [103, 105, 114, 97, 102, 102, 101] |
| llama   | [108, 108, 97, 109, 97]            |
+---------+------------------------------------+

以下示例将 BYTES 的整数表示形式转换为对应的 ASCII 字符值。

SELECT word, TO_CODE_POINTS(word) AS bytes_value_as_integer
FROM UNNEST([b'\x00\x01\x10\xff', b'\x66\x6f\x6f']) AS word;

+------------------+------------------------+
| word             | bytes_value_as_integer |
+------------------+------------------------+
| \x00\x01\x10\xff | [0, 1, 16, 255]        |
| foo              | [102, 111, 111]        |
+------------------+------------------------+

以下示例演示了一个 BYTES 结果与一个 STRING 结果之间的区别。

SELECT TO_CODE_POINTS(b'Ā') AS b_result, TO_CODE_POINTS('Ā') AS s_result;

+------------+----------+
| b_result   | s_result |
+------------+----------+
| [196, 128] | [256]    |
+------------+----------+

请注意字符 Ā 表示为两个字节的 Unicode 序列。因此,TO_CODE_POINTS 的 BYTES 版本会返回包含两个元素的数组,而 STRING 版本会返回包含单独一个元素的数组。

TO_HEX

TO_HEX(bytes)

说明

将 BYTES 序列转换为十六进制 STRING。将 STRING 中的各字节转换为 (0..9, a..f) 范围内的两个十六进制字符。要将十六进制编码的 STRING 转换为 BYTES,可以使用 FROM_HEX

返回类型

STRING

示例

WITH Input AS (
  SELECT b'\x00\x01\x02\x03\xAA\xEE\xEF\xFF' AS byte_str UNION ALL
  SELECT b'foobar'
)
SELECT byte_str, TO_HEX(byte_str) AS hex_str
FROM Input;
+----------------------------------+------------------+
| byte_string                      | hex_string       |
+----------------------------------+------------------+
| foobar                           | 666f6f626172     |
| \x00\x01\x02\x03\xaa\xee\xef\xff | 00010203aaeeefff |
+----------------------------------+------------------+

TRIM

TRIM(value1[, value2])

说明

移除与 value2 匹配的所有前导和尾随字符。如果未指定 value2,则移除所有前导和尾随空格(如 Unicode 标准定义)。如果第一个参数是 BYTES 类型,则必须提供第二个参数。

如果 value2 包含多个字符或字节,则函数会移除 value2 中包含的所有前导/尾随字符或字节。

返回类型

STRING 或 BYTES

示例

WITH items AS
  (SELECT "   apple   " as item
  UNION ALL
  SELECT "   banana   " as item
  UNION ALL
  SELECT "   orange   " as item)

SELECT
  CONCAT("#", TRIM(item), "#") as example
FROM items;

+----------+
| example  |
+----------+
| #apple#  |
| #banana# |
| #orange# |
+----------+

WITH items AS
  (SELECT "***apple***" as item
  UNION ALL
  SELECT "***banana***" as item
  UNION ALL
  SELECT "***orange***" as item)

SELECT
  TRIM(item, "*") as example
FROM items;

+---------+
| example |
+---------+
| apple   |
| banana  |
| orange  |
+---------+

WITH items AS
  (SELECT "xxxapplexxx" as item
  UNION ALL
  SELECT "yyybananayyy" as item
  UNION ALL
  SELECT "zzzorangezzz" as item
  UNION ALL
  SELECT "xyzpearxyz" as item)

SELECT
  TRIM(item, "xyz") as example
FROM items;

+---------+
| example |
+---------+
| apple   |
| banana  |
| orange  |
| pear    |
+---------+

UPPER

UPPER(value)

说明

对于 STRING 参数,返回所有字母字符均为大写的原始字符串。根据 Unicode 字符数据库在大写与小写之间进行映射,不考虑特定语言的映射。

对于 BYTES 参数,参数被视为 ASCII 文本且大于 127 的所有字节保持不变。

返回类型

STRING 或 BYTES

示例

WITH items AS
  (SELECT
    "foo" as item
  UNION ALL
  SELECT
    "bar" as item
  UNION ALL
  SELECT
    "baz" as item)

SELECT
  UPPER(item) AS example
FROM items;

+---------+
| example |
+---------+
| FOO     |
| BAR     |
| BAZ     |
+---------+

JSON 函数

BigQuery 支持帮助您检索 JSON 格式字符串内存储的数据的函数,以及帮助您将数据转化为 JSON 格式字符串的函数。

JSON_EXTRACT 或 JSON_EXTRACT_SCALAR

JSON_EXTRACT(json_string_expr, json_path_string_literal),返回 STRING 格式的 JSON 值。

JSON_EXTRACT_SCALAR(json_string_expr, json_path_string_literal),返回 STRING 格式的标量 JSON 值。

说明

json_string_expr 参数必须是 JSON 格式的字符串。例如:

{"class" : {"students" : [{"name" : "Jane"}]}}

json_path_string_literal 参数标识您希望从 JSON 格式的字符串中获取的一个或多个值。您应使用 JSONPath 格式构造此参数。作为此格式的一部分,此参数必须以 $ 符号开头,这个符号标识的就是 JSON 格式字符串的最外层。您可以使用圆点或括号表示法来标识子值。如果 JSON 对象是数组,则可以使用括号指定数组索引。

JSONPath 说明
$ 根对象或元素
. 或 [] 子运算符
[] 下标运算符

如果 json_path_string_literal 参数与 json_string_expr 中的值不匹配,两个函数均会返回 NULL。如果 JSON_EXTRACT_SCALAR 的选定值不是标量,例如一个对象或一个数组,该函数会返回 NULL

如果 JSONPath 无效,这些函数会引发错误。

如果 JSON 密钥使用无效的 JSONPath 字符,您可以使用单引号和括号 [' '] 对这些字符进行转义。例如:

SELECT JSON_EXTRACT_SCALAR('{"a.b": {"c": "world"}}', "$['a.b'].c") as hello;

+-------+
| hello |
+-------+
| world |
+-------+

示例

SELECT JSON_EXTRACT(json_text, '$') AS json_text_string
FROM UNNEST([
  '{"class" : {"students" : [{"name" : "Jane"}]}}',
  '{"class" : {"students" : []}}',
  '{"class" : {"students" : [{"name" : "John"}, {"name": "Jamie"}]}}'
  ]) AS json_text;

以上查询会生成以下结果:

+-----------------------------------------------------------+
| json_text_string                                          |
+-----------------------------------------------------------+
| {"class":{"students":[{"name":"Jane"}]}}                  |
| {"class":{"students":[]}}                                 |
| {"class":{"students":[{"name":"John"},{"name":"Jamie"}]}} |
+-----------------------------------------------------------+
SELECT JSON_EXTRACT(json_text, '$.class.students[0]') AS first_student
FROM UNNEST([
  '{"class" : {"students" : [{"name" : "Jane"}]}}',
  '{"class" : {"students" : []}}',
  '{"class" : {"students" : [{"name" : "John"}, {"name": "Jamie"}]}}'
  ]) AS json_text;

以上查询会生成以下结果:

+-----------------+
| first_student   |
+-----------------+
| {"name":"Jane"} |
| NULL            |
| {"name":"John"} |
+-----------------+
SELECT JSON_EXTRACT(json_text, '$.class.students[1].name') AS second_student_name
FROM UNNEST([
  '{"class" : {"students" : [{"name" : "Jane"}]}}',
  '{"class" : {"students" : []}}',
  '{"class" : {"students" : [{"name" : "John"}, {"name": "Jamie"}]}}'
  ]) AS json_text;

以上查询会生成以下结果:

+-------------------+
| second_student    |
+-------------------+
| NULL              |
| NULL              |
| "Jamie"           |
+-------------------+
SELECT JSON_EXTRACT(json_text, "$.class['students']") AS student_names
FROM UNNEST([
  '{"class" : {"students" : [{"name" : "Jane"}]}}',
  '{"class" : {"students" : []}}',
  '{"class" : {"students" : [{"name" : "John"}, {"name": "Jamie"}]}}'
  ]) AS json_text;

以上查询会生成以下结果:

+------------------------------------+
| student_names                      |
+------------------------------------+
| [{"name":"Jane"}]                  |
| []                                 |
| [{"name":"John"},{"name":"Jamie"}] |
+------------------------------------+
SELECT JSON_EXTRACT('{ "name" : "Jakob", "age" : "6" }', '$.name') as json_name,
  JSON_EXTRACT_SCALAR('{ "name" : "Jakob", "age" : "6" }', '$.name') as scalar_name,
  JSON_EXTRACT('{ "name" : "Jakob", "age" : "6" }', '$.age') as json_age,
  JSON_EXTRACT_SCALAR('{ "name" : "Jakob", "age" : "6" }', '$.age') as scalar;

以上查询会生成以下结果:

+-----------+-------------+----------+--------+
| json_name | scalar_name | json_age | scalar |
+-----------+-------------+----------+--------+
| "Jakob"   | Jakob       | "6"      | 6      |
+-----------+-------------+----------+--------+

TO_JSON_STRING

TO_JSON_STRING(value[, pretty_print])

说明

返回 value 的 JSON 格式的字符串表示形式。此函数支持支持可选的 pretty_print 参数。如果存在 pretty_print,返回值将以易读性为目标进行格式设置。

输入数据类型 返回值
任意类型的 NULL null
BOOL truefalse
INT64

value 在 [-253, 253] 范围(即可以无损地表示为 IEEE 754 双精度浮点数的整数的范围)内时,与 CAST(value AS STRING) 相同。此范围以外的值采用带引号的字符串形式表示。例如:

-1
0
12345678901
9007199254740992
-9007199254740992
"9007199254740993"

9007199254740993 大于 253,因此表示为带英文引号的字符串。

NUMERIC

value 在 [-253, 253] 范围内并且没有小数部分时,与 CAST(value AS STRING) 相同。此范围以外的值采用带引号的字符串形式表示。例如:

-1
0
"9007199254740993"
"123.56"


FLOAT64 +/-infNaN 分别表示为 Infinity-InfinityNaN

其余情况与 CAST(value AS STRING) 相同。

STRING 带引号的字符串值,根据 JSON 标准进行转义。具体来说,"\ 和从 U+0000U+001F 的控制字符会予以转义。
BYTES

带引号的 RFC 4648 base64 转义值。例如:

"R29vZ2xl" 是字节 b"Google" 的 base64 表示

DATE

带引号的日期。例如:

"2017-03-06"
TIMESTAMP

带引号的 ISO 8601 日期时间,其中 T 分隔日期和时间,Zulu/UTC 表示时区。例如:

"2017-03-06T12:34:56.789012Z"
DATETIME

带引号的 ISO 8601 日期时间,其中 T 分隔日期和时间。例如:

"2017-03-06T12:34:56.789012"
TIME

带引号的 ISO 8601 时间。例如:

"12:34:56.789012"
ARRAY

[elem1,elem2,...],其中每个 elem 均根据元素类型进行格式化。

格式化示例:

[
  elem1,
  elem2,
  ...
]

其中每个元素均根据元素类型进行格式化。空数组表示为 []

STRUCT {"field_name1":field_value1,"field_name2":field_value2,...}

其中的各 field_value 根据其类型进行格式化。

格式化示例:

{
  "field_name1": field_value1,
  "field_name2": field_value2,
  ...
}

其中的各 field_value 根据其类型进行格式化。如果 field_value 是非空 ARRAY 或 STRUCT,元素会缩进到适当的级别。空结构体表示为 {}

名称重复的字段可能导致无法解析的 JSON。匿名字段用 "" 表示。

无效 UTF-8 字段名称可能导致无法解析的 JSON。字符串值根据 JSON 标准进行转义。具体来说,"\ 和从 U+0000U+001F 的控制字符会予以转义。

返回类型

值的 JSON 字符串表示形式。

示例

将表中的行转换为 JSON。

WITH Input AS (
  SELECT [1, 2] AS x, 'foo' AS y, STRUCT(true AS a, DATE '2017-04-05' AS b) AS s UNION ALL
  SELECT NULL AS x, '' AS y, STRUCT(false AS a, DATE '0001-01-01' AS b) AS s UNION ALL
  SELECT [3] AS x, 'bar' AS y, STRUCT(NULL AS a, DATE '2016-12-05' AS b) AS s
)
SELECT
  t,
  TO_JSON_STRING(t) AS json_row
FROM Input AS t;

以上查询会生成以下结果:

+-----------------------------------+-------------------------------------------------------+
| t                                 | json_row                                              |
+-----------------------------------+-------------------------------------------------------+
| {[1, 2], foo, {true, 2017-04-05}} | {"x":[1,2],"y":"foo","s":{"a":true,"b":"2017-04-05"}} |
| {NULL, , {false, 0001-01-01}}     | {"x":null,"y":"","s":{"a":false,"b":"0001-01-01"}}    |
| {[3], bar, {NULL, 2016-12-05}}    | {"x":[3],"y":"bar","s":{"a":null,"b":"2016-12-05"}}   |
+-----------------------------------+-------------------------------------------------------+

通过格式化将表中的行转换为 JSON。

WITH Input AS (
  SELECT [1, 2] AS x, 'foo' AS y, STRUCT(true AS a, DATE '2017-04-05' AS b) AS s UNION ALL
  SELECT NULL AS x, '' AS y, STRUCT(false AS a, DATE '0001-01-01' AS b) AS s UNION ALL
  SELECT [3] AS x, 'bar' AS y, STRUCT(NULL AS a, DATE '2016-12-05' AS b) AS s
)
SELECT
  TO_JSON_STRING(t, true) AS json_row
FROM Input AS t;

以上查询产生以下结果:

+-----------------------+
| json_row              |
+-----------------------+
| {                     |
|  "x": [               |
|    1,                 |
|    2                  |
|  ],                   |
|  "y": "foo",          |
|  "s": {               |
|    "a": true,         |
|    "b": "2017-04-05"  |
|  }                    |
|}                      |
| {                     |
|  "x": null,           |
|  "y": "",             |
|  "s": {               |
|    "a": false,        |
|    "b": "0001-01-01"  |
|  }                    |
|}                      |
| {                     |
|  "x": [               |
|    3                  |
|  ],                   |
|  "y": "bar",          |
|  "s": {               |
|    "a": null,         |
|    "b": "2016-12-05"  |
|  }                    |
|}                      |
+-----------------------+

数组函数

ARRAY

ARRAY(subquery)

说明

ARRAY 函数返回一个 ARRAY,其中子查询中的每一行都对应一个元素。

如果 subquery 生成一个 SQL 表,则此表必须只能包含一列。ARRAY 输出中的每个元素都是此表中这一列某行的值。

如果 subquery 生成一个值表,则输出 ARRAY 中的每个元素都是该值表中相应的一整行。

限制条件

  • 子查询是无序的,因此不保证输出 ARRAY 的元素为子查询保留源表中的任何顺序。但是,如果子查询包含 ORDER BY 子句,则 ARRAY 函数将返回一个遵循此子句的 ARRAY
  • 如果子查询返回多个列,则 ARRAY 函数返回一个错误。
  • 如果子查询返回 ARRAY 类型的列或 ARRAY 类型的行,则 ARRAY 函数会返回错误:BigQuery 不支持元素类型为 ARRAYARRAY
  • 如果子查询未返回任何行,则 ARRAY 函数返回一个空的 ARRAY。它始终不会返回 NULL ARRAY

返回类型

ARRAY

示例

SELECT ARRAY
  (SELECT 1 UNION ALL
   SELECT 2 UNION ALL
   SELECT 3) AS new_array;

+-----------+
| new_array |
+-----------+
| [1, 2, 3] |
+-----------+

要通过包含多个列的子查询构造 ARRAY,请将子查询改为使用 SELECT AS STRUCT。如此,ARRAY 函数将返回由 STRUCT 组成的 ARRAY。对于子查询中的每一行,ARRAY 都包含一个 STRUCT,并且其中每个 STRUCT 都包含一个字段,对应于该行中的每一列。

SELECT
  ARRAY
    (SELECT AS STRUCT 1, 2, 3
     UNION ALL SELECT AS STRUCT 4, 5, 6) AS new_array;

+------------------------+
| new_array              |
+------------------------+
| [{1, 2, 3}, {4, 5, 6}] |
+------------------------+

同样地,要根据包含一个或多个 ARRAY 的子查询构造 ARRAY,请将子查询改为使用 SELECT AS STRUCT

SELECT ARRAY
  (SELECT AS STRUCT [1, 2, 3] UNION ALL
   SELECT AS STRUCT [4, 5, 6]) AS new_array;

+----------------------------+
| new_array                  |
+----------------------------+
| [{[1, 2, 3]}, {[4, 5, 6]}] |
+----------------------------+

ARRAY_CONCAT

ARRAY_CONCAT(array_expression_1 [, array_expression_n])

说明

将一个或多个具有相同元素类型的数组连接为一个数组。

返回类型

ARRAY

示例

SELECT ARRAY_CONCAT([1, 2], [3, 4], [5, 6]) as count_to_six;

+--------------------------------------------------+
| count_to_six                                     |
+--------------------------------------------------+
| [1, 2, 3, 4, 5, 6]                               |
+--------------------------------------------------+

ARRAY_LENGTH

ARRAY_LENGTH(array_expression)

说明

返回数组的大小。如果数组为空,则返回 0。如果 array_expressionNULL,则返回 NULL

返回类型

INT64

示例

WITH items AS
  (SELECT ["apples", "bananas", NULL, "grapes"] as list
  UNION ALL
  SELECT ["coffee", "tea", "milk" ] as list
  UNION ALL
  SELECT ["cake", "pie"] as list)

SELECT list, ARRAY_LENGTH(list) AS size
FROM items
ORDER BY size DESC;

+---------------------------------+------+
| list                            | size |
+---------------------------------+------+
| [apples, bananas, NULL, grapes] | 4    |
| [coffee, tea, milk]             | 3    |
| [cake, pie]                     | 2    |
+---------------------------------+------+

ARRAY_TO_STRING

ARRAY_TO_STRING(array_expression, delimiter[, null_text])

说明

array_expression 中的元素连接起来并作为 STRING 返回。array_expression 的值可以是 STRING 数组,也可以是 BYTES 数据类型。

如果使用了 null_text 参数,该函数会将数组中的任何 NULL 值替换为 null_text 值。

如果未使用 null_text 参数,该函数会忽略 NULL 值及其前置分隔符。

示例

WITH items AS
  (SELECT ["apples", "bananas", "pears", "grapes"] as list
  UNION ALL
  SELECT ["coffee", "tea", "milk" ] as list
  UNION ALL
  SELECT ["cake", "pie", NULL] as list)

SELECT ARRAY_TO_STRING(list, '--') AS text
FROM items;

+--------------------------------+
| text                           |
+--------------------------------+
| apples--bananas--pears--grapes |
| coffee--tea--milk              |
| cake--pie                      |
+--------------------------------+

WITH items AS
  (SELECT ["apples", "bananas", "pears", "grapes"] as list
  UNION ALL
  SELECT ["coffee", "tea", "milk" ] as list
  UNION ALL
  SELECT ["cake", "pie", NULL] as list)

SELECT ARRAY_TO_STRING(list, '--', 'MISSING') AS text
FROM items;

+--------------------------------+
| text                           |
+--------------------------------+
| apples--bananas--pears--grapes |
| coffee--tea--milk              |
| cake--pie--MISSING             |
+--------------------------------+

GENERATE_ARRAY

GENERATE_ARRAY(start_expression, end_expression[, step_expression])

说明

返回一个值数组。start_expressionend_expression 参数确定数组的开始值和结束值(包含边界值)。

GENERATE_ARRAY 函数接受以下数据类型的输入:

  • INT64
  • NUMERIC
  • FLOAT64

step_expression 参数确定用于生成数组值的增量。此参数的默认值是 1

如果 step_expression 设置为 0 或者有任何输入为 NaN,此函数将返回错误。

如果任意参数为 NULL,该函数将返回一个 NULL 数组。

返回数据类型

ARRAY

示例

以下命令返回一个整数数组,默认步长为 1。

SELECT GENERATE_ARRAY(1, 5) AS example_array;

+-----------------+
| example_array   |
+-----------------+
| [1, 2, 3, 4, 5] |
+-----------------+

以下命令使用用户指定的步长返回一个数组。

SELECT GENERATE_ARRAY(0, 10, 3) AS example_array;

+---------------+
| example_array |
+---------------+
| [0, 3, 6, 9]  |
+---------------+

以下命令使用负值步长 -3 返回一个数组。

SELECT GENERATE_ARRAY(10, 0, -3) AS example_array;

+---------------+
| example_array |
+---------------+
| [10, 7, 4, 1] |
+---------------+

以下命令返回一个 start_expressionend_expression 的值相同的数组。

SELECT GENERATE_ARRAY(4, 4, 10) AS example_array;

+---------------+
| example_array |
+---------------+
| [4]           |
+---------------+

以下代码返回一个空数组,因为 start_expression 大于 end_expressionstep_expression 值为正数。

SELECT GENERATE_ARRAY(10, 0, 3) AS example_array;

+---------------+
| example_array |
+---------------+
| []            |
+---------------+

以下命令返回一个 NULL 数组,因为 end_expressionNULL

SELECT GENERATE_ARRAY(5, NULL, 1) AS example_array;

+---------------+
| example_array |
+---------------+
| NULL          |
+---------------+

以下命令返回多个数组。

SELECT GENERATE_ARRAY(start, 5) AS example_array
FROM UNNEST([3, 4, 5]) AS start;

+---------------+
| example_array |
+---------------+
| [3, 4, 5]     |
| [4, 5]        |
| [5]           |
+---------------+

GENERATE_DATE_ARRAY

GENERATE_DATE_ARRAY(start_date, end_date[, INTERVAL INT64_expr date_part])

说明

返回一个日期数组。start_dateend_date 参数确定数组边界的开始值和结束值。

GENERATE_DATE_ARRAY 函数接受以下数据类型的输入:

  • start_date 必须是 DATE
  • end_date 必须是 DATE
  • INT64_expr 必须是 INT64
  • date_part 必须是 DAY、WEEK、MONTH、QUARTER 或 YEAR。

INT64_expr 参数确定用于生成日期的增量。此参数的默认值是 1 天。

如果 INT64_expr 设置为 0,此函数会返回错误。

返回数据类型

包含 0 个或多个 DATE 值的 ARRAY。

示例

以下命令使用默认步长 1 返回日期数组。

SELECT GENERATE_DATE_ARRAY('2016-10-05', '2016-10-08') AS example;

+--------------------------------------------------+
| example                                          |
+--------------------------------------------------+
| [2016-10-05, 2016-10-06, 2016-10-07, 2016-10-08] |
+--------------------------------------------------+

以下命令使用用户指定的步长返回一个数组。

SELECT GENERATE_DATE_ARRAY(
 '2016-10-05', '2016-10-09', INTERVAL 2 DAY) AS example;

+--------------------------------------+
| example                              |
+--------------------------------------+
| [2016-10-05, 2016-10-07, 2016-10-09] |
+--------------------------------------+

以下命令使用负值步长 -3 返回一个数组。

SELECT GENERATE_DATE_ARRAY('2016-10-05',
  '2016-10-01', INTERVAL -3 DAY) AS example;

+--------------------------+
| example                  |
+--------------------------+
| [2016-10-05, 2016-10-02] |
+--------------------------+

以下命令将 start_dateend_date 设为相同值并返回一个数组。

SELECT GENERATE_DATE_ARRAY('2016-10-05',
  '2016-10-05', INTERVAL 8 DAY) AS example;

+--------------+
| example      |
+--------------+
| [2016-10-05] |
+--------------+

以下命令返回一个空数组,因为 start_date 大于 end_date,且 step 值为正数。

SELECT GENERATE_DATE_ARRAY('2016-10-05',
  '2016-10-01', INTERVAL 1 DAY) AS example;

+---------+
| example |
+---------+
| []      |
+---------+

以下命令返回一个 NULL 数组,因为其输入之一是 NULL

SELECT GENERATE_DATE_ARRAY('2016-10-05', NULL) AS example;

+---------+
| example |
+---------+
| NULL    |
+---------+

以下命令使用 MONTH 作为 date_part 间隔值返回一个日期数组。

SELECT GENERATE_DATE_ARRAY('2016-01-01',
  '2016-12-31', INTERVAL 2 MONTH) AS example;

+--------------------------------------------------------------------------+
| example                                                                  |
+--------------------------------------------------------------------------+
| [2016-01-01, 2016-03-01, 2016-05-01, 2016-07-01, 2016-09-01, 2016-11-01] |
+--------------------------------------------------------------------------+

以下命令使用非常量日期生成一个数组。

WITH StartsAndEnds AS (
  SELECT DATE '2016-01-01' AS date_start, DATE '2016-01-31' AS date_end
  UNION ALL SELECT DATE "2016-04-01", DATE "2016-04-30"
  UNION ALL SELECT DATE "2016-07-01", DATE "2016-07-31"
  UNION ALL SELECT DATE "2016-10-01", DATE "2016-10-31"
)
SELECT GENERATE_DATE_ARRAY(date_start, date_end, INTERVAL 1 WEEK) AS date_range
FROM StartsAndEnds;

+--------------------------------------------------------------+
| date_range                                                   |
+--------------------------------------------------------------+
| [2016-01-01, 2016-01-08, 2016-01-15, 2016-01-22, 2016-01-29] |
| [2016-04-01, 2016-04-08, 2016-04-15, 2016-04-22, 2016-04-29] |
| [2016-07-01, 2016-07-08, 2016-07-15, 2016-07-22, 2016-07-29] |
| [2016-10-01, 2016-10-08, 2016-10-15, 2016-10-22, 2016-10-29] |
+--------------------------------------------------------------+

GENERATE_TIMESTAMP_ARRAY

GENERATE_TIMESTAMP_ARRAY(start_timestamp, end_timestamp,
                         INTERVAL step_expression date_part)

说明

返回由 TIMESTAMPS 组成,并按指定时间间隔隔开的 ARRAYstart_timestampend_timestamp 参数确定 ARRAY 的上限和下限(包含上限值和下限值)。

GENERATE_TIMESTAMP_ARRAY 函数接受以下数据类型的输入:

  • start_timestampTIMESTAMP
  • end_timestampTIMESTAMP
  • step_expressionINT64
  • 允许的 date_part 值包括

MICROSECONDMILLISECOND

SECONDMINUTEHOURDAY

step_expression 参数确定用于生成时间戳的增量。

返回数据类型

包含 0 个或更多个 TIMESTAMP 值的 ARRAY

示例

以下示例返回时间间隔为 1 秒的 TIMESTAMP ARRAY

SELECT GENERATE_TIMESTAMP_ARRAY('2016-10-05 00:00:00', '2016-10-05 00:00:02',
                                INTERVAL 1 SECOND) AS timestamp_array;

+--------------------------------------------------------------------------+
| timestamp_array                                                          |
+--------------------------------------------------------------------------+
| [2016-10-05 00:00:00+00, 2016-10-05 00:00:01+00, 2016-10-05 00:00:02+00] |
+--------------------------------------------------------------------------+

以下示例返回时间间隔为负数的 TIMESTAMPS ARRAY

SELECT GENERATE_TIMESTAMP_ARRAY('2016-10-06 00:00:00', '2016-10-01 00:00:00',
                                INTERVAL -2 DAY) AS timestamp_array;

+--------------------------------------------------------------------------+
| timestamp_array                                                          |
+--------------------------------------------------------------------------+
| [2016-10-06 00:00:00+00, 2016-10-04 00:00:00+00, 2016-10-02 00:00:00+00] |
+--------------------------------------------------------------------------+

以下示例返回只包含一个元素的 ARRAY,因为 start_timestampend_timestamp 的值相同。

SELECT GENERATE_TIMESTAMP_ARRAY('2016-10-05 00:00:00', '2016-10-05 00:00:00',
                                INTERVAL 1 HOUR) AS timestamp_array;

+--------------------------+
| timestamp_array          |
+--------------------------+
| [2016-10-05 00:00:00+00] |
+--------------------------+

以下示例返回一个空 ARRAY,因为 start_timestamp 晚于 end_timestamp

SELECT GENERATE_TIMESTAMP_ARRAY('2016-10-06 00:00:00', '2016-10-05 00:00:00',
                                INTERVAL 1 HOUR) AS timestamp_array;

+-----------------+
| timestamp_array |
+-----------------+
| []              |
+-----------------+

以下示例返回一个 null ARRAY,因为有一项输入为 NULL

SELECT GENERATE_TIMESTAMP_ARRAY('2016-10-05 00:00:00', NULL, INTERVAL 1 HOUR)
  AS timestamp_array;

+-----------------+
| timestamp_array |
+-----------------+
| NULL            |
+-----------------+

以下示例根据包含 start_timestampend_timestamp 值的列生成 TIMESTAMP ARRAY

SELECT GENERATE_TIMESTAMP_ARRAY(start_timestamp, end_timestamp, INTERVAL 1 HOUR)
  AS timestamp_array
FROM
  (SELECT
    TIMESTAMP '2016-10-05 00:00:00' AS start_timestamp,
    TIMESTAMP '2016-10-05 02:00:00' AS end_timestamp
   UNION ALL
   SELECT
    TIMESTAMP '2016-10-05 12:00:00' AS start_timestamp,
    TIMESTAMP '2016-10-05 14:00:00' AS end_timestamp
   UNION ALL
   SELECT
    TIMESTAMP '2016-10-05 23:59:00' AS start_timestamp,
    TIMESTAMP '2016-10-06 01:59:00' AS end_timestamp);

+--------------------------------------------------------------------------+
| timestamp_array                                                          |
+--------------------------------------------------------------------------+
| [2016-10-05 00:00:00+00, 2016-10-05 01:00:00+00, 2016-10-05 02:00:00+00] |
| [2016-10-05 12:00:00+00, 2016-10-05 13:00:00+00, 2016-10-05 14:00:00+00] |
| [2016-10-05 23:59:00+00, 2016-10-06 00:59:00+00, 2016-10-06 01:59:00+00] |
+--------------------------------------------------------------------------+

OFFSET 和 ORDINAL

array_expression[OFFSET(zero_based_offset)]
array_expression[ORDINAL(one_based_offset)]

说明

按位置访问 ARRAY 元素并返回该元素。OFFSET 表示从 0 开始计数,ORDINAL 表示从 1 开始计数。

给定数组要么解释为从 0 开始,要么解释为从 1 开始。访问数组元素时,必须在数组位置之前分别附加 OFFSETORDINAL;该行为并非默认行为。

如果索引超出范围,OFFSETORDINAL 都会生成错误。

返回类型

因 ARRAY 中的元素而异。

示例

WITH items AS
  (SELECT ["apples", "bananas", "pears", "grapes"] as list
  UNION ALL
  SELECT ["coffee", "tea", "milk" ] as list
  UNION ALL
  SELECT ["cake", "pie"] as list)

SELECT list, list[OFFSET(1)] as offset_1, list[ORDINAL(1)] as ordinal_1
FROM items;

+----------------------------------+-----------+-----------+
| list                             | offset_1  | ordinal_1 |
+----------------------------------+-----------+-----------+
| [apples, bananas, pears, grapes] | bananas   | apples    |
| [coffee, tea, milk]              | tea       | coffee    |
| [cake, pie]                      | pie       | cake      |
+----------------------------------+-----------+-----------+

ARRAY_REVERSE

ARRAY_REVERSE(value)

说明

按照输入 ARRAY 中元素的反向顺序返回该 ARRAY。

返回类型

ARRAY

示例

WITH example AS (
  SELECT [1, 2, 3] AS arr UNION ALL
  SELECT [4, 5] AS arr UNION ALL
  SELECT [] AS arr
)
SELECT
  arr,
  ARRAY_REVERSE(arr) AS reverse_arr
FROM example;

+-----------+-------------+
| arr       | reverse_arr |
+-----------+-------------+
| [1, 2, 3] | [3, 2, 1]   |
| [4, 5]    | [5, 4]      |
| []        | []          |
+-----------+-------------+

SAFE_OFFSET 和 SAFE_ORDINAL

array_expression[SAFE_OFFSET(zero_based_offset)]
array_expression[SAFE_ORDINAL(one_based_offset)]

说明

基本等同于 OFFSETORDINAL,不同之处在于,如果索引超出范围,则返回 NULL

返回类型

因 ARRAY 中的元素而异。

示例

WITH items AS
  (SELECT ["apples", "bananas", "pears", "grapes"] as list
  UNION ALL
  SELECT ["coffee", "tea", "milk" ] as list
  UNION ALL
  SELECT ["cake", "pie"] as list)

SELECT list,
  list[SAFE_OFFSET(3)] as safe_offset_3,
  list[SAFE_ORDINAL(3)] as safe_ordinal_3
FROM items;

+----------------------------------+---------------+----------------+
| list                             | safe_offset_3 | safe_ordinal_3 |
+----------------------------------+---------------+----------------+
| [apples, bananas, pears, grapes] | grapes        | pears          |
| [coffee, tea, milk]              | NULL          | milk           |
| [cake, pie]                      | NULL          | NULL           |
+----------------------------------+---------------+----------------+

日期函数

BigQuery 支持以下 DATE 函数。

CURRENT_DATE

CURRENT_DATE([time_zone])

说明

返回指定或默认时区的当前日期。

此函数支持可选的 time_zone 参数。此参数是表示要使用的时区的字符串。如果未指定时区,则使用默认时区世界协调时间 (UTC)。要了解如何指定时区,请参阅时区定义

如果 time_zone 参数的计算结果为 NULL,此函数会返回 NULL

返回数据类型

DATE

示例

SELECT CURRENT_DATE() as the_date;

+--------------+
| the_date     |
+--------------+
| 2016-12-25   |
+--------------+

EXTRACT

EXTRACT(part FROM date_expression)

说明

返回与指定的日期部分相对应的值。part 必须是下述项之一:

  • DAYOFWEEK:返回 [1,7] 范围内的值,其中星期日是一周的第一天。
  • DAY
  • DAYOFYEAR
  • WEEK:返回 [0, 53] 范围内的日期的周数。一周从星期日开始算起,一年第一个星期日之前的日期属于第 0 周。

  • WEEK(<WEEKDAY>):返回 [0, 53] 范围内的日期的周数。一周从 WEEKDAY 开始算起,一年第一个 WEEKDAY 之前的日期为第 0 周。WEEKDAY 的有效值包括 SUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAY

  • ISOWEEK:以 ISO 8601 格式返回 date_expression 的周数。ISOWEEK 从星期一开始算起。返回值在 [1, 53] 范围内。每个 ISO 格式年份的第一个 ISOWEEK 从阳历年第一个星期四之前的星期一开始算起。
  • MONTH
  • QUARTER:返回 [1,4] 范围内的值。
  • YEAR
  • ISOYEAR:以 ISO 8601 格式返回周编号年份(即为包含 date_expression 所在一周中的星期四的公历年)。

返回数据类型

INT64

示例

在以下示例中,EXTRACT 返回了 DAY 时间部分对应的值。

SELECT EXTRACT(DAY FROM DATE '2013-12-25') as the_day;

+---------+
| the_day |
+---------+
| 25      |
+---------+

下例中,EXTRACT 返回了与日期一列中接近年末的不同的时间部分相对应的值。

SELECT
  date,
  EXTRACT(ISOYEAR FROM date) AS isoyear,
  EXTRACT(ISOWEEK FROM date) AS isoweek,
  EXTRACT(YEAR FROM date) AS year,
  EXTRACT(WEEK FROM date) AS week
FROM UNNEST(GENERATE_DATE_ARRAY('2015-12-23', '2016-01-09')) AS date
ORDER BY date;
+------------+---------+---------+------+------+
| date       | isoyear | isoweek | year | week |
+------------+---------+---------+------+------+
| 2015-12-23 | 2015    | 52      | 2015 | 51   |
| 2015-12-24 | 2015    | 52      | 2015 | 51   |
| 2015-12-25 | 2015    | 52      | 2015 | 51   |
| 2015-12-26 | 2015    | 52      | 2015 | 51   |
| 2015-12-27 | 2015    | 52      | 2015 | 52   |
| 2015-12-28 | 2015    | 53      | 2015 | 52   |
| 2015-12-29 | 2015    | 53      | 2015 | 52   |
| 2015-12-30 | 2015    | 53      | 2015 | 52   |
| 2015-12-31 | 2015    | 53      | 2015 | 52   |
| 2016-01-01 | 2015    | 53      | 2016 | 0    |
| 2016-01-02 | 2015    | 53      | 2016 | 0    |
| 2016-01-03 | 2015    | 53      | 2016 | 1    |
| 2016-01-04 | 2016    | 1       | 2016 | 1    |
| 2016-01-05 | 2016    | 1       | 2016 | 1    |
| 2016-01-06 | 2016    | 1       | 2016 | 1    |
| 2016-01-07 | 2016    | 1       | 2016 | 1    |
| 2016-01-08 | 2016    | 1       | 2016 | 1    |
| 2016-01-09 | 2016    | 1       | 2016 | 1    |
+------------+---------+---------+------+------+

在以下示例中,date_expression 属于星期日。EXTRACT 使用从星期日开始的周数计算第一列,并使用从星期一开始的周数计算第二列。

WITH table AS (SELECT DATE('2017-11-05') AS date)
SELECT
  date,
  EXTRACT(WEEK(SUNDAY) FROM date) AS week_sunday,
  EXTRACT(WEEK(MONDAY) FROM date) AS week_monday FROM table;

+------------+-------------+-------------+
| date       | week_sunday | week_monday |
+------------+-------------+-------------+
| 2017-11-05 | 45          | 44          |
+------------+-------------+-------------+

DATE

1. DATE(year, month, day)
2. DATE(timestamp_expression[, timezone])

说明

  1. 根据表示年月日的 INT64 值构造 DATE。
  2. timestamp_expression 转换为 DATE 数据类型。它支持使用可选参数来指定时区。如果未指定时区,则使用默认时区世界协调时间 (UTC)。

返回数据类型

DATE

示例

SELECT
  DATE(2016, 12, 25) as date_ymd,
  DATE(TIMESTAMP "2016-12-25 05:30:00+07", "America/Los_Angeles") as date_tstz;

+------------+------------+
| date_ymd   | date_tstz  |
+------------+------------+
| 2016-12-25 | 2016-12-24 |
+------------+------------+

DATE_ADD

DATE_ADD(date_expression, INTERVAL INT64_expr date_part)

说明

向 DATE 添加指定的时间间隔。

DATE_ADD 支持以下 date_part 值:

  • DAY
  • WEEK。等于 7 DAY
  • MONTH
  • QUARTER
  • YEAR

如果日期是(或接近)月份的最后一天,则需要特殊处理 MONTH、QUARTER 和 YEAR 部分。如果生成月份的天数少于原始日期的天数,则生成日期作为下一月的最后一天。

返回数据类型

DATE

示例

SELECT DATE_ADD(DATE "2008-12-25", INTERVAL 5 DAY) as five_days_later;

+--------------------+
| five_days_later    |
+--------------------+
| 2008-12-30         |
+--------------------+

DATE_SUB

DATE_SUB(date_expression, INTERVAL INT64_expr date_part)

说明

从 DATE 中减去指定的日期间隔。

DATE_SUB 支持以下 date_part 值:

  • DAY
  • WEEK。等于 7 DAY
  • MONTH
  • QUARTER
  • YEAR

如果日期是(或接近)月份的最后一天,则需要特殊处理 MONTH、QUARTER 和 YEAR 部分。如果生成月份的天数少于原始日期的天数,则生成日期作为下一月的最后一天。

返回数据类型

DATE

示例

SELECT DATE_SUB(DATE "2008-12-25", INTERVAL 5 DAY) as five_days_ago;

+---------------+
| five_days_ago |
+---------------+
| 2008-12-20    |
+---------------+

DATE_DIFF

DATE_DIFF(date_expression, date_expression, date_part)

说明

返回两个 date_part 之间的 date_expression 边界数。如果第一个日期发生在第二个日期之前,则结果为非正数。

DATE_DIFF 支持以下 date_part 值:

  • DAY
  • WEEK:此日期部分从星期日开始。
  • WEEK(<WEEKDAY>):此日期部分从 WEEKDAY 开始。WEEKDAY 的有效值包括 SUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAY
  • ISOWEEK:使用 ISO 8601 格式的周边界值。ISO 格式的周从星期一开始。
  • MONTH
  • QUARTER
  • YEAR
  • ISOYEAR:使用 ISO 8601 格式的周编号年份边界值。ISO 格式年份的边界值是星期四属于相应公历年的第一周的星期一。

返回数据类型

INT64

示例

SELECT DATE_DIFF(DATE '2010-07-07', DATE '2008-12-25', DAY) as days_diff;

+-----------+
| days_diff |
+-----------+
| 559       |
+-----------+
SELECT
  DATE_DIFF(DATE '2017-10-15', DATE '2017-10-14', DAY) as days_diff,
  DATE_DIFF(DATE '2017-10-15', DATE '2017-10-14', WEEK) as weeks_diff;

+-----------+------------+
| days_diff | weeks_diff |
+-----------+------------+
| 1         | 1          |
+-----------+------------+

上面的示例展示了连续两天的 DATE_DIFF 结果。 对日期部分 WEEK 执行 DATE_DIFF 运算会返回 1,因为 DATE_DIFF 会计算此日期范围内日期部分边界值的数量。每个 WEEK 都从星期日开始,因此在 2017-10-14 星期六与 2017-10-15 星期日之间有一个日期部分的边界值。

以下示例显示了不同年份中两个日期的 DATE_DIFF 结果。对日期部分 YEAR 执行 DATE_DIFF 运算会返回 3,因为它计算两个日期之间的公历年边界值数量。对日期部分 ISOYEAR 执行 DATE_DIFF 运算会返回 2,因为第二个日期属于 ISO 格式的年份 2015。阳历年 2015 年的第一个星期四是 2015-01-01,因此 ISO 格式年份 2015 年开始于上一个星期一,也就是 2014-12-29。

SELECT
  DATE_DIFF('2017-12-30', '2014-12-30', YEAR) AS year_diff,
  DATE_DIFF('2017-12-30', '2014-12-30', ISOYEAR) AS isoyear_diff;

+-----------+--------------+
| year_diff | isoyear_diff |
+-----------+--------------+
| 3         | 2            |
+-----------+--------------+

以下示例显示连续两天的 DATE_DIFF 结果。第一个日期是星期一,第二个日期是星期日。对日期部分 WEEK 执行 DATE_DIFF 运算会返回 0,因为此时间部分使用从星期日开始的周。对日期部分 WEEK(MONDAY) 执行 DATE_DIFF 运算会返回 1。对日期部分 ISOWEEK 执行 DATE_DIFF 运算也会返回 1,因为 ISO 格式的周从星期一开始。

SELECT
  DATE_DIFF('2017-12-18', '2017-12-17', WEEK) AS week_diff,
  DATE_DIFF('2017-12-18', '2017-12-17', WEEK(MONDAY)) AS week_weekday_diff,
  DATE_DIFF('2017-12-18', '2017-12-17', ISOWEEK) AS isoweek_diff;

+-----------+-------------------+--------------+
| week_diff | week_weekday_diff | isoweek_diff |
+-----------+-------------------+--------------+
| 0         | 1                 | 1            |
+-----------+-------------------+--------------+

DATE_TRUNC

DATE_TRUNC(date_expression, date_part)

说明

将日期截断到指定的粒度。

DATE_TRUNC 支持以下 date_part 值:

  • DAY
  • WEEK
  • WEEK(<WEEKDAY>):将 date_expression 截断到上一周边界值,每周从 WEEKDAY 开始。WEEKDAY 的有效值包括 SUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAY
  • ISOWEEK:将 date_expression 截断到上一个 ISO 8601 格式的周边界值。ISOWEEK 从星期一开始算起。每个 ISO 格式年份的第一个 ISOWEEK 都包含对应阳历年的第一个星期四。早于此日期的任何 date_expression 均会截断到上一个星期一。
  • MONTH
  • QUARTER
  • YEAR
  • ISOYEAR:将 date_expression 截断到上一个 ISO 8601 格式的周编号年份边界值。ISO 格式年份的边界值是星期四属于相应公历年的第一周的星期一。

返回数据类型

DATE

示例

SELECT DATE_TRUNC(DATE '2008-12-25', MONTH) as month;

+------------+
| month      |
+------------+
| 2008-12-01 |
+------------+

在以下示例中,原始日期是星期日。由于 date_partWEEK(MONDAY)DATE_TRUNC 会返回上一个星期一的 DATE

SELECT date AS original, DATE_TRUNC(date, WEEK(MONDAY)) AS truncated
FROM (SELECT DATE('2017-11-05') AS date);

+------------+------------+
| original   | truncated  |
+------------+------------+
| 2017-11-05 | 2017-10-30 |
+------------+------------+

在以下示例中,原始 date_expression 是阳历年 2015 年。但对日期部分 ISOYEAR 执行 DATE_TRUNC 会将 date_expression 截断到 ISO 格式年份的开端,而非阳历年的开端。阳历年 2015 年的第一个星期四是 2015-01-01,因此 ISO 格式年份 2015 年开始于上一个星期一,也就是 2014-12-29。因此,date_expression 2015-06-15 之前的 ISO 格式年份边界值是 2014-12-29。

SELECT
  DATE_TRUNC('2015-06-15', ISOYEAR) AS isoyear_boundary,
  EXTRACT(ISOYEAR FROM DATE '2015-06-15') AS isoyear_number;

+------------------+----------------+
| isoyear_boundary | isoyear_number |
+------------------+----------------+
| 2014-12-29       | 2015           |
+------------------+----------------+

DATE_FROM_UNIX_DATE

DATE_FROM_UNIX_DATE(INT64_expression)

说明

INT64_expression 解释为从 1970-01-01 开始计算的天数。

返回数据类型

DATE

示例

SELECT DATE_FROM_UNIX_DATE(14238) as date_from_epoch;

+-----------------+
| date_from_epoch |
+-----------------+
| 2008-12-25      |
+-----------------+

FORMAT_DATE

FORMAT_DATE(format_string, date_expr)

说明

根据指定的 format_string 格式化 date_expr

要查看此函数支持的格式元素列表,请参阅 DATE 支持的格式元素

返回数据类型

STRING

示例

SELECT FORMAT_DATE("%x", DATE "2008-12-25") as US_format;

+------------+
| US_format  |
+------------+
| 12/25/08   |
+------------+

PARSE_DATE

PARSE_DATE(format_string, date_string)

说明

使用 format_string 和日期的字符串表示形式返回一个 DATE 对象。

使用 PARSE_DATE 时,请注意以下几点:

  • 未指定的字段。 任何未指定的字段在初始化时均以 1970-01-01 为准加以确定。
  • 不区分大小写的名称。 MondayFebruary 等名称不区分大小写。
  • 空格。 格式字符串中的一个或更多连续空格与日期字符串中的零个或更多连续空格相匹配。此外,始终可在日期字符串中使用前导空格和尾随空格(即使这些空格不在格式字符串中)。
  • 格式优先。 如果两个(或更多)格式元素的信息出现重叠(例如 %F%Y 均对年份有影响),则最后一个元素通常会替换前面的所有元素。

要查看此函数支持的格式元素列表,请参阅 DATE 支持的格式元素

返回数据类型

DATE

示例

SELECT PARSE_DATE("%x", "12/25/08") as parsed;

+------------+
| parsed     |
+------------+
| 2008-12-25 |
+------------+

UNIX_DATE

UNIX_DATE(date_expression)

说明

返回从 1970-01-01 开始计算的天数。

返回数据类型

INT64

示例

SELECT UNIX_DATE(DATE "2008-12-25") as days_from_epoch;

+-----------------+
| days_from_epoch |
+-----------------+
| 14238           |
+-----------------+

DATE 支持的格式元素

除非另有说明,否则使用格式字符串的 DATE 函数均支持以下元素:

格式元素 说明
%A 星期几的全名。
%a 星期几的缩写名称。
%B 月份的全名。
%b 或 %h 月份的缩写名称。
%C 用十进制数 (00-99) 表示的年份的前两位数(年份除以 100 并只取整数)。
%D 采用 %m/%d/%y 格式的日期。
%d 用十进制数 (01-31) 表示的月份中的某一天。
%e 用十进制数 (1-31) 表示的月份中的某一天;个位数前面附加一个空格。
%F 采用 %Y-%m-%d 格式的日期。
%G 用十进制数表示的四位数的 ISO 8601 格式年份。每个 ISO 格式年份开始于公历年的第一个星期四之前的星期一。请注意,%G 和 %Y 可能会在公历年边界值附近产生不同的结果,其中公历年和 ISO 格式年份可能会有所不同。
%g 用十进制数 (00-99) 表示的两位数的 ISO 8601 格式年份。每个 ISO 格式年份开始于公历年的第一个星期四之前的星期一。请注意,%G 和 %Y 可能会在公历年边界值附近产生不同的结果,其中公历年和 ISO 格式年份可能会有所不同。
%j 用十进制数 (001-366) 表示的一年中的某一天。
%m 用十进制数 (01-12) 表示的月份。
%n 换行符。
%t 制表符。
%U 用十进制数 (00-53) 表示的一年中的周数(星期日算作一周的第一天)。
%u 用十进制数 (1-7) 表示的星期名称(星期一算作一周的第一天)。
%V 用十进制数 (01-53) 表示的一年中的周数(星期一算作一周的第一天)。如果包含 1 月 1 日的那一周有 4 天或超过 4 天属于新的一年,则该周为第 1 周;否则为上一年的第 53 周,而下一周为新年的第 1 周。
%W 用十进制数 (00-53) 表示的一年的周数(星期一算作一周的第一天)。
%w 用十进制数 (0-6) 表示的星期名称(星期日算作一周的第一天)。
%x 采用 MM/DD/YY 格式表示的日期。
%Y 用十进制数表示的四位数的年份。
%y 用十进制数 (00-99) 表示的后两位数的年份,前导零可选填。可与 %C 混用。如果未指定 %C,则 00-68 年为 2000 年代,而 69-99 年为 1900 年代。
%E4Y 四个字符的年份 (0001 ... 9999)。注意:%Y 将生成尽量多的字符数以完整显示年份。

日期时间函数

BigQuery 支持以下 DATETIME 函数。

CURRENT_DATETIME

CURRENT_DATETIME([timezone])

说明

以 DATETIME 对象的形式返回当前时间。

此函数支持可选的 timezone 参数。要了解如何指定时区,请参阅时区定义

返回数据类型

DATETIME

示例

SELECT CURRENT_DATETIME() as now;

+----------------------------+
| now                        |
+----------------------------+
| 2016-05-19 10:38:47.046465 |
+----------------------------+

DATETIME

1. DATETIME(year, month, day, hour, minute, second)
2. DATETIME(date_expression, time_expression)
3. DATETIME(timestamp_expression [, timezone])

说明

  1. 使用表示年、月、日、小时、分钟和秒钟的 INT64 值构造 DATETIME 对象。
  2. 使用一个 DATE 对象和一个 TIME 对象构造 DATETIME 对象。
  3. 使用一个 TIMESTAMP 对象构造 DATETIME 对象。它支持使用可选参数来指定时区。如果未指定时区,则使用默认时区世界协调时间 (UTC)。

返回数据类型

DATETIME

示例

SELECT
  DATETIME(2008, 12, 25, 05, 30, 00) as datetime_ymdhms,
  DATETIME(TIMESTAMP "2008-12-25 05:30:00+00", "America/Los_Angeles") as datetime_tstz;

+---------------------+---------------------+
| datetime_ymdhms     | datetime_tstz       |
+---------------------+---------------------+
| 2008-12-25 05:30:00 | 2008-12-24 21:30:00 |
+---------------------+---------------------+

DATETIME_ADD

DATETIME_ADD(datetime_expression, INTERVAL INT64_expr part)

说明

向 DATETIME 对象添加 INT64_expr 个单位的 part

DATETIME_ADD 支持以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR
  • DAY
  • WEEK。等于 7 DAY
  • MONTH
  • QUARTER
  • YEAR

如果日期是(或接近)月份的最后一天,则需要特殊处理 MONTH、QUARTER 和 YEAR 部分。如果由此所得到的月份的天数少于原始 DATETIME 的天数,则所得到的日期作为下一月的最后一天。

返回数据类型

DATETIME

示例

SELECT
  DATETIME "2008-12-25 15:30:00" as original_date,
  DATETIME_ADD(DATETIME "2008-12-25 15:30:00", INTERVAL 10 MINUTE) as later;

+-----------------------------+------------------------+
| original_date               | later                  |
+-----------------------------+------------------------+
| 2008-12-25 15:30:00         | 2008-12-25 15:40:00    |
+-----------------------------+------------------------+

DATETIME_SUB

DATETIME_SUB(datetime_expression, INTERVAL INT64_expr part)

说明

从 DATETIME 中减去 INT64_expr 个单位的 part

DATETIME_SUB 支持以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR
  • DAY
  • WEEK。等于 7 DAY
  • MONTH
  • QUARTER
  • YEAR

如果日期是(或接近)月份的最后一天,则需要特殊处理 MONTH、QUARTER 和 YEAR 部分。如果由此所得到的月份的天数少于原始 DATETIME 的天数,则所得到的日期作为下一月的最后一天。

返回数据类型

DATETIME

示例

SELECT
  DATETIME "2008-12-25 15:30:00" as original_date,
  DATETIME_SUB(DATETIME "2008-12-25 15:30:00", INTERVAL 10 MINUTE) as earlier;

+-----------------------------+------------------------+
| original_date               | earlier                |
+-----------------------------+------------------------+
| 2008-12-25 15:30:00         | 2008-12-25 15:20:00    |
+-----------------------------+------------------------+

DATETIME_DIFF

DATETIME_DIFF(datetime_expression, datetime_expression, part)

说明

返回两个 datetime_expression 之间的 part 边界值数量。如果第一个 DATETIME 发生在第二个 DATETIME 之前,则结果为非正数。如果计算结果超过结果类型的最大值(例如两个 DATETIME 对象之间的微秒数之差超过一个 INT64 最大值),则会引发一个错误。

DATETIME_DIFF 支持以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR
  • DAY
  • WEEK:此日期部分从星期日开始。
  • WEEK(<WEEKDAY>):此日期部分从 WEEKDAY 开始。WEEKDAY 的有效值包括 SUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAY
  • ISOWEEK:使用 ISO 8601 格式的周边界值。ISO 格式的周从星期一开始。
  • MONTH
  • QUARTER
  • YEAR
  • ISOYEAR:使用 ISO 8601 格式的周编号年份边界值。ISO 格式年份的边界值是星期四属于相应公历年的第一周的星期一。

返回数据类型

INT64

示例

SELECT
  DATETIME "2010-07-07 10:20:00" as first_datetime,
  DATETIME "2008-12-25 15:30:00" as second_datetime,
  DATETIME_DIFF(DATETIME "2010-07-07 10:20:00",
    DATETIME "2008-12-25 15:30:00", DAY) as difference;

+----------------------------+------------------------+------------------------+
| first_datetime             | second_datetime        | difference             |
+----------------------------+------------------------+------------------------+
| 2010-07-07 10:20:00        | 2008-12-25 15:30:00    | 559                    |
+----------------------------+------------------------+------------------------+
SELECT
  DATETIME_DIFF(DATETIME '2017-10-15 00:00:00',
    DATETIME '2017-10-14 00:00:00', DAY) as days_diff,
  DATETIME_DIFF(DATETIME '2017-10-15 00:00:00',
    DATETIME '2017-10-14 00:00:00', WEEK) as weeks_diff;

+-----------+------------+
| days_diff | weeks_diff |
+-----------+------------+
| 1         | 1          |
+-----------+------------+

上面的示例显示了相隔 24 小时的两个 DATETIMEDATETIME_DIFF 结果。对部分 WEEK 执行 DATETIME_DIFF 运算会返回 1,因为 DATETIME_DIFF 会对此 DATETIME 范围内的部分边界值数量进行计数。每个 WEEK 都从星期日开始,因此在 2017-10-14 00:00:00 星期六与 2017-10-15 00:00:00 星期日之间有一个日期部分的边界值。

以下示例显示了不同年份中两个日期的 DATETIME_DIFF 结果。对日期部分 YEAR 执行 DATETIME_DIFF 运算会返回 3,因为它会计算两个 DATETIME 之间的公历年边界值数量。对日期部分 ISOYEAR 执行 DATETIME_DIFF 运算会返回 2,因为第二个 DATETIME 属于 ISO 格式的年份 2015。阳历年 2015 年的第一个星期四是 2015-01-01,因此 ISO 格式年份 2015 年开始于上一个星期一,也就是 2014-12-29。

SELECT
  DATETIME_DIFF('2017-12-30 00:00:00',
    '2014-12-30 00:00:00', YEAR) AS year_diff,
  DATETIME_DIFF('2017-12-30 00:00:00',
    '2014-12-30 00:00:00', ISOYEAR) AS isoyear_diff;

+-----------+--------------+
| year_diff | isoyear_diff |
+-----------+--------------+
| 3         | 2            |
+-----------+--------------+

以下示例显示了连续两天的 DATETIME_DIFF 结果。第一个日期是星期一,第二个日期是星期日。对日期部分 WEEK 执行 DATETIME_DIFF 运算会返回 0,因为此时间部分使用从星期日开始的周。对日期部分 WEEK(MONDAY) 执行 DATETIME_DIFF 运算会返回 1。对日期部分 ISOWEEK 执行 DATETIME_DIFF 运算也会返回 1,因为 ISO 格式的周从星期一开始。

SELECT
  DATETIME_DIFF('2017-12-18', '2017-12-17', WEEK) AS week_diff,
  DATETIME_DIFF('2017-12-18', '2017-12-17', WEEK(MONDAY)) AS week_weekday_diff,
  DATETIME_DIFF('2017-12-18', '2017-12-17', ISOWEEK) AS isoweek_diff;

+-----------+-------------------+--------------+
| week_diff | week_weekday_diff | isoweek_diff |
+-----------+-------------------+--------------+
| 0         | 1                 | 1            |
+-----------+-------------------+--------------+

DATETIME_TRUNC

DATETIME_TRUNC(datetime_expression, part)

说明

DATETIME 对象截断到 part 的粒度。

DATETIME_TRUNC 支持以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR
  • DAY
  • WEEK
  • WEEK(<WEEKDAY>):将 datetime_expression 截断到上一个周边界值,每周从 WEEKDAY 开始。WEEKDAY 的有效值包括 SUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAY
  • ISOWEEK:将 datetime_expression 截断到上一个 ISO 8601 格式的周边界值。ISOWEEK 从星期一开始算起。每个 ISO 格式年份的第一个 ISOWEEK 都包含对应阳历年的第一个星期四。早于此日期的任何 date_expression 均会截断到上一个星期一。
  • MONTH
  • QUARTER
  • YEAR
  • ISOYEAR:将 datetime_expression 截断到上一个 ISO 8601 格式的周编号年份边界值。ISO 格式年份的边界值是星期四属于相应公历年的第一周的星期一。

返回数据类型

DATETIME

示例

SELECT
  DATETIME "2008-12-25 15:30:00" as original,
  DATETIME_TRUNC(DATETIME "2008-12-25 15:30:00", DAY) as truncated;

+----------------------------+------------------------+
| original                   | truncated              |
+----------------------------+------------------------+
| 2008-12-25 15:30:00        | 2008-12-25 00:00:00    |
+----------------------------+------------------------+

在以下示例中,原始 DATETIME 是星期日。由于 partWEEK(MONDAY)DATE_TRUNC 会返回上一个星期一的 DATETIME

SELECT
 datetime AS original,
 DATETIME_TRUNC(datetime, WEEK(MONDAY)) AS truncated
FROM (SELECT DATETIME(TIMESTAMP '2017-11-05 00:00:00') AS datetime);

+---------------------+---------------------+
| original            | truncated           |
+---------------------+---------------------+
| 2017-11-05 00:00:00 | 2017-10-30 00:00:00 |
+---------------------+---------------------+

在以下示例中,原始 datetime_expression 是阳历年 2015 年。但对日期部分 ISOYEAR 执行 DATETIME_TRUNC 会将 datetime_expression 截断到 ISO 格式年份的开端,而非阳历年的开端。阳历年 2015 年的第一个星期四是 2015-01-01,因此 ISO 格式年份 2015 年开始于上一个星期一,也就是 2014-12-29。因此,datetime_expression 2015-06-15 00:00:00 之前的 ISO 格式年份边界值是 2014-12-29。

SELECT
  DATETIME_TRUNC('2015-06-15 00:00:00', ISOYEAR) AS isoyear_boundary,
  EXTRACT(ISOYEAR FROM DATETIME '2015-06-15 00:00:00') AS isoyear_number;

+---------------------+----------------+
| isoyear_boundary    | isoyear_number |
+---------------------+----------------+
| 2014-12-29 00:00:00 | 2015           |
+---------------------+----------------+

FORMAT_DATETIME

FORMAT_DATETIME(format_string, datetime_expression)

说明

根据指定的 format_string 设置 DATETIME 对象的格式。如需查看此函数支持的格式元素列表,请参阅 DATETIME 支持的格式元素

返回数据类型

STRING

示例

SELECT
  FORMAT_DATETIME("%c", DATETIME "2008-12-25 15:30:00")
  AS formatted;

PARSE_DATETIME

PARSE_DATETIME(format_string, string)

说明

使用 DATETIMEformat_stringSTRING 表示形式返回 DATETIME。如需查看此函数支持的格式元素列表,请参阅 DATETIME 支持的格式元素

PARSE_DATETIME 根据以下规则解析 string

  • 未指定的字段。 任何未指定的字段在初始化时均以 1970-01-01 00:00:00.0 为准。例如,如果未指定年份,则默认为 1970
  • 不区分大小写的名称。 诸如 MondayFebruary 之类的名称不区分大小写。
  • 空格。 格式化字符串中的一个或多个连续空格与 DATETIME 字符串中的零个或多个连续空格相匹配。此外,DATETIME 字符串始终支持使用前导空格和尾随空格(即使这些空格不在格式化字符串中)。
  • 格式优先。 如果两个或更多格式元素的信息出现重叠,则最后一个元素通常会替换前面的所有元素,但要注意存在一些例外情况。例如,%F%Y 均对年份有影响,因此前面的元素会替换后面的元素。请参阅 DATETIME 支持的格式元素中关于 %s%C%y 的说明。

示例

以下示例将 STRING 字面量解析为 DATETIME

SELECT PARSE_DATETIME('%Y-%m-%d %H:%M:%S', '1998-10-18 13:45:55') AS datetime;

以上查询返回以下输出:

+---------------------+
| datetime            |
+---------------------+
| 1998-10-18 13:45:55 |
+---------------------+

以下示例将包含日期(以自然语言格式显示)的 STRING 字面量解析为 DATETIME

SELECT PARSE_DATETIME('%A, %B %e, %Y','Wednesday, December 19, 2018')
  AS datetime;

以上查询返回以下输出:

+---------------------+
| datetime            |
+---------------------+
| 2018-12-19 00:00:00 |
+---------------------+

返回数据类型

DATETIME

DATETIME 支持的格式元素

除非另有说明,否则使用格式字符串的 DATETIME 函数均支持以下元素:

格式元素 说明
%A 星期几的全名。
%a 星期几的缩写名称。
%B 月份的全名。
%b 或 %h 月份的缩写名称。
%C 用十进制数 (00-99) 表示的世纪(年份除以 100 并截断为整数)。
%c 表示日期和时间。
%D 采用 %m/%d/%y 格式的日期。
%d 用十进制数 (01-31) 表示的月份中的某一天。
%e 用十进制数 (1-31) 表示的月份中的某一天;个位数前面附加一个空格。
%F 采用 %Y-%m-%d 格式的日期。
%G 用十进制数表示的四位数的 ISO 8601 格式年份。每个 ISO 格式年份开始于公历年的第一个星期四之前的星期一。请注意,%G 和 %Y 可能会在公历年边界值附近产生不同的结果,其中公历年和 ISO 格式年份可能会有所不同。
%g 用十进制数 (00-99) 表示的两位数的 ISO 8601 格式年份。每个 ISO 格式年份开始于公历年的第一个星期四之前的星期一。请注意,%G 和 %Y 可能会在公历年边界值附近产生不同的结果,其中公历年和 ISO 格式年份可能会有所不同。
%H 用十进制数 (00-23) 表示的小时数(24 小时制)。
%I 用十进制数 (01-12) 表示的小时数(12 小时制)。
%j 用十进制数 (001-366) 表示的一年中的某一天。
%k 用十进制数 (0-23) 表示的小时数(24 小时制);个位数前面附加一个空格。
%l 用十进制数 (1-12) 表示的小时数(12 小时制);个位数前面附加一个空格。
%M 用十进制数 (00-59) 表示的分钟数。
%m 用十进制数 (01-12) 表示的月份。
%n 换行符。
%P am 或 pm。
%p AM 或 PM。
%R 采用 %H:%M 格式显示的时间。
%r 使用 AM/PM 标记法表示的 12 小时制的时间。
%S 用十进制数 (00-60) 表示的秒数。
%s 从 1970-01-01 00:00:00 开始计算的秒数。无论 %s 出现在字符串的哪个位置,始终替换所有其他格式元素。如果出现多个 %s 元素,则以最后一个元素为准。
%T 采用 %H:%M:%S 格式表示的时间。
%t 制表符。
%U 用十进制数 (00-53) 表示的一年中的周数(星期日算作一周的第一天)。
%u 用十进制数 (1-7) 表示的星期名称(星期一算作一周的第一天)。
%V 用十进制数 (01-53) 表示的一年中的周数(星期一算作一周的第一天)。如果包含 1 月 1 日的那一周有 4 天或超过 4 天属于新的一年,则该周为第 1 周;否则为上一年的第 53 周,而下一周为新年的第 1 周。
%W 用十进制数 (00-53) 表示的一年的周数(星期一算作一周的第一天)。
%w 用十进制数 (0-6) 表示的星期名称(星期日算作一周的第一天)。
%X 采用 HH:MM:SS 格式表示的时间。
%x 采用 MM/DD/YY 格式表示的日期。
%Y 用十进制数表示的四位数的年份。
%y 用十进制数 (00-99) 表示的后两位数的年份,前导零可选填。可与 %C 混用。如果未指定 %C,则 00-68 年为 2000 年代,而 69-99 年为 1900 年代。
%% 单个 % 字符。
%E#S 具有 # 位小数精度的秒数。
%E*S 具有完整小数精度的秒数(字面量“*”)。
%E4Y 四个字符的年份 (0001 ... 9999)。注意:%Y 将生成尽量多的字符数以完整显示年份。

时间函数

BigQuery 支持以下 TIME 函数。

CURRENT_TIME

CURRENT_TIME()

说明

以 TIME 对象的形式返回当前时间。

返回数据类型

TIME

示例

SELECT CURRENT_TIME() as now;

+----------------------------+
| now                        |
+----------------------------+
| 15:31:38.776361            |
+----------------------------+

TIME

1. TIME(hour, minute, second)
2. TIME(timestamp, [timezone])
3. TIME(datetime)

说明

  1. 使用表示小时、分钟和秒钟的 INT64 值构造 TIME 对象。
  2. 使用一个 TIMESTAMP 对象构造一个 TIME 对象。它支持使用可选参数来指定时区。如果未指定时区,则使用默认时区世界协调时间 (UTC)。
  3. 使用一个 DATETIME 对象构造一个 TIME 对象。

返回数据类型

TIME

示例

SELECT
  TIME(15, 30, 00) as time_hms,
  TIME(TIMESTAMP "2008-12-25 15:30:00+08", "America/Los_Angeles") as time_tstz;
+----------+-----------+
| time_hms | time_tstz |
+----------+-----------+
| 15:30:00 | 23:30:00  |
+----------+-----------+
SELECT
  TIME(DATETIME "2008-12-25 15:30:00.000000") AS time_dt;
+----------+
| time_dt  |
+----------+
| 15:30:00 |
+----------+

TIME_ADD

TIME_ADD(time_expression, INTERVAL INT64_expr part)

说明

向 TIME 对象添加 INT64_expr 个单位的 part

TIME_ADD 支持以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR

当值超出 00:00:00 到 24:00:00 的边界值时,此函数会自动调整。例如,如果您向 23:30:00 添加了 1 小时,返回值则为 00:30:00

返回数据类型

TIME

示例

SELECT
  TIME "15:30:00" as original_time,
  TIME_ADD(TIME "15:30:00", INTERVAL 10 MINUTE) as later;

+-----------------------------+------------------------+
| original_time               | later                  |
+-----------------------------+------------------------+
| 15:30:00                    | 15:40:00               |
+-----------------------------+------------------------+

TIME_SUB

TIME_SUB(time_expression, INTERVAL INT_expr part)

说明

从 TIME 对象中减去 INT64_expr 个单位的 part

TIME_SUB 支持以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR

当值超出 00:00:00 到 24:00:00 的边界值时,此函数会自动调整。例如,如果您从 00:30:00 减去了 1 小时,返回值则为 23:30:00

返回数据类型

TIME

示例

SELECT
  TIME "15:30:00" as original_date,
  TIME_SUB(TIME "15:30:00", INTERVAL 10 MINUTE) as earlier;

+-----------------------------+------------------------+
| original_date                | earlier                |
+-----------------------------+------------------------+
| 15:30:00                    | 15:20:00               |
+-----------------------------+------------------------+

TIME_DIFF

TIME_DIFF(time_expression, time_expression, part)

说明

返回两个 TIME 对象之间所指定的整个 part 间隔数。如果计算结果超过结果类型的最大值(例如两个 TIME 对象之间的微秒数之差超过 INT64 值的最大值),则引发一个错误。

TIME_DIFF 支持以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR

返回数据类型

INT64

示例

SELECT
  TIME "15:30:00" as first_time,
  TIME "14:35:00" as second_time,
  TIME_DIFF(TIME "15:30:00", TIME "14:35:00", MINUTE) as difference;

+----------------------------+------------------------+------------------------+
| first_time                 | second_time            | difference             |
+----------------------------+------------------------+------------------------+
| 15:30:00                   | 14:35:00               | 55                     |
+----------------------------+------------------------+------------------------+

TIME_TRUNC

TIME_TRUNC(time_expression, part)

说明

将 TIME 对象截断到 part 的粒度。

TIME_TRUNC 支持以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR

返回数据类型

TIME

示例

SELECT
  TIME "15:30:00" as original,
  TIME_TRUNC(TIME "15:30:00", HOUR) as truncated;

+----------------------------+------------------------+
| original                   | truncated              |
+----------------------------+------------------------+
| 15:30:00                   | 15:00:00               |
+----------------------------+------------------------+

FORMAT_TIME

FORMAT_TIME(format_string, time_object)

说明 根据指定的 format_string 设置 TIME 对象的格式。如需查看此函数支持的格式元素列表,请参阅 TIME 支持的格式元素

返回数据类型

STRING

示例

SELECT FORMAT_TIME("%R", TIME "15:30:00") as formatted_time;

+----------------+
| formatted_time |
+----------------+
| 15:30          |
+----------------+

PARSE_TIME

PARSE_TIME(format_string, string)

说明

使用 format_string 和字符串返回一个 TIME 对象。如需查看此函数支持的格式元素列表,请参阅 TIME 支持的格式元素

使用 PARSE_TIME 时,请注意以下几点:

  • 未指定的字段。 任何未指定的字段在初始化时均以 00:00:00.0 为准。例如,如果未指定 seconds,则默认为 00,依此类推。
  • 空格。 格式字符串中的一个或更多连续空格与 TIME 字符串中的零个或更多连续空格相匹配。此外,始终可在 TIME 字符串中使用前导空格和尾随空格(即使这些空格不在格式字符串中)。
  • 格式优先。 如果两个(或更多)格式元素的信息出现重叠,则最后一个元素通常会替换前面的所有元素。

返回数据类型

TIME

示例

SELECT PARSE_TIME("%H", "15") as parsed_time;

+-------------+
| parsed_time |
+-------------+
| 15:00:00    |
+-------------+

TIME 支持的格式元素

除非另有说明,否则使用格式字符串的 TIME 函数均支持以下元素:

格式元素 说明
%H 用十进制数 (00-23) 表示的小时数(24 小时制)。
%I 用十进制数 (01-12) 表示的小时数(12 小时制)。
%j 用十进制数 (001-366) 表示的一年中的某一天。
%k 用十进制数 (0-23) 表示的小时数(24 小时制);个位数前面附加一个空格。
%l 用十进制数 (1-12) 表示的小时数(12 小时制);个位数前面附加一个空格。
%M 用十进制数 (00-59) 表示的分钟数。
%n 换行符。
%P am 或 pm。
%p AM 或 PM。
%R 采用 %H:%M 格式表示的时间。
%r 使用 AM/PM 标记法表示的 12 小时制的时间。
%S 用十进制数 (00-60) 表示的秒数。
%T 采用 %H:%M:%S 格式表示的时间。
%t 制表符。
%X 采用 HH:MM:SS 格式表示的时间。
%% 单个 % 字符。
%E#S 具有 # 位小数精度的秒数。
%E*S 具有完整小数精度的秒数(字面量“*”)。

时间戳函数

BigQuery 支持以下 TIMESTAMP 函数。

注意:如果发生溢出,这些函数会返回运行时错误;结果值受到所定义的日期和时间戳最小值/最大值限制。

CURRENT_TIMESTAMP

CURRENT_TIMESTAMP()

说明

括号是可选项。此函数在 20 个小时的时段中围绕插入的闰秒进行模糊处理。 CURRENT_TIMESTAMP() 生成一个 TIMESTAMP 值,该值是连续非模糊的值,每分钟刚好 60 秒,不会重复闰秒期间的值。

支持的输入类型

不适用

结果数据类型

TIMESTAMP

示例

SELECT CURRENT_TIMESTAMP() as now;

+-------------------------------+
| now                           |
+-------------------------------+
| 2016-05-16 18:12:47.145482+00 |
+-------------------------------+

EXTRACT

EXTRACT(part FROM timestamp_expression [AT TIME ZONE tz_spec])

说明

从提供的 INT64 中返回与指定的 part 相对应的 timestamp_expression 值。

可使用以下 part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR
  • DAYOFWEEK
  • DAY
  • DAYOFYEAR
  • WEEK:返回 [0, 53] 范围内的日期的周数。一周从星期日开始算起,一年第一个星期日之前的日期属于第 0 周。

  • WEEK(<WEEKDAY>):返回 [0, 53] 范围内的 timestamp_expression 的周数。一周从 WEEKDAY 开始算起,一年第一个 WEEKDAY 之前的 datetime 属于第 0 周。WEEKDAY 的有效值包括 SUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAY

  • ISOWEEK:以 ISO 8601 格式返回 datetime_expression 的周数。ISOWEEK 从星期一开始算起。返回值在 [1, 53] 范围内。每个 ISO 格式年份的第一个 ISOWEEK 从公历年第一个星期四之前的星期一开始算起。

  • MONTH
  • QUARTER
  • YEAR
  • ISOYEAR:以 ISO 8601 格式返回周编号年份(即为包含 date_expression 所在一周的星期四的公历年)。
  • DATE
  • DATETIME
  • TIME

返回的值会掉低位时间段。例如,提取秒数时,EXTRACT 会截掉毫秒值和微秒值。

如需了解如何指定时区,请参阅时区定义

返回数据类型

通常是 INT64。如果 partDATE,则返回 DATE

示例

在以下示例中,EXTRACT 返回了 DAY 时间部分对应的值。

SELECT EXTRACT(DAY
  FROM TIMESTAMP "2008-12-25 15:30:00" AT TIME ZONE "America/Los_Angeles")
  AS the_day;

+------------+
| the_day    |
+------------+
| 25         |
+------------+

下例中,EXTRACT 返回了与时间戳的一列中不同的时间部分相对应的值。

WITH Timestamps AS (
  SELECT TIMESTAMP '2005-01-03 12:34:56' AS timestamp UNION ALL
  SELECT TIMESTAMP '2007-12-31' UNION ALL
  SELECT TIMESTAMP '2009-01-01' UNION ALL
  SELECT TIMESTAMP '2009-12-31' UNION ALL
  SELECT TIMESTAMP '2017-01-02' UNION ALL
  SELECT TIMESTAMP '2017-05-26'
)
SELECT
  timestamp,
  EXTRACT(ISOYEAR FROM timestamp) AS isoyear,
  EXTRACT(ISOWEEK FROM timestamp) AS isoweek,
  EXTRACT(YEAR FROM timestamp) AS year,
  EXTRACT(WEEK FROM timestamp) AS week
FROM Timestamps
ORDER BY timestamp;
+------------------------+---------+---------+------+------+
| timestamp              | isoyear | isoweek | year | week |
+------------------------+---------+---------+------+------+
| 2005-01-03 12:34:56+00 | 2005    | 1       | 2005 | 1    |
| 2007-12-31 00:00:00+00 | 2008    | 1       | 2007 | 52   |
| 2009-01-01 00:00:00+00 | 2009    | 1       | 2009 | 0    |
| 2009-12-31 00:00:00+00 | 2009    | 53      | 2009 | 52   |
| 2017-01-02 00:00:00+00 | 2017    | 1       | 2017 | 1    |
| 2017-05-26 00:00:00+00 | 2017    | 21      | 2017 | 21   |
+------------------------+---------+---------+------+------+

在以下示例中,timestamp_expression 属于星期日。EXTRACT 使用从星期日开始的周数计算第一列,并使用从星期一开始的周数计算第二列。

WITH table AS (SELECT TIMESTAMP('2017-11-05 00:00:00') AS timestamp)
SELECT
  timestamp,
  EXTRACT(WEEK(SUNDAY) FROM timestamp) AS week_sunday,
  EXTRACT(WEEK(MONDAY) FROM timestamp) AS week_monday
FROM table;

+------------------------+-------------+---------------+
| timestamp              | week_sunday | week_monday |
+------------------------+-------------+---------------+
| 2017-11-05 00:00:00+00 | 45          | 44            |
+------------------------+-------------+---------------+

STRING

STRING(timestamp_expression[, timezone])

说明

timestamp_expression 转换为 STRING 数据类型。支持使用可选参数来指定时区。要了解如何指定时区,请参阅时区定义

返回数据类型

STRING

示例

SELECT STRING(TIMESTAMP "2008-12-25 15:30:00", "America/Los_Angeles") as string;

+-------------------------------+
| string                        |
+-------------------------------+
| 2008-12-25 15:30:00-08        |
+-------------------------------+

TIMESTAMP

1. TIMESTAMP(string_expression[, timezone])
2. TIMESTAMP(date_expression[, timezone])
3. TIMESTAMP(datetime_expression[, timezone])

说明

  1. 将 STRING 表达式转换为 TIMESTAMP 数据类型。

  2. 将 DATE 对象转换为 TIMESTAMP 数据类型。

  3. 将 DATETIME 对象转换为 TIMESTAMP 数据类型。

此函数支持使用可选参数来指定时区。如果未指定时区,则使用默认时区世界协调时间 (UTC)。

返回数据类型

TIMESTAMP

示例

SELECT
  CAST(TIMESTAMP("2008-12-25 15:30:00", "America/Los_Angeles") AS STRING) AS timestamp_str,
  CAST(TIMESTAMP(DATE "2008-12-25", "America/Los_Angeles") AS STRING) AS timestamp_date,
  CAST(TIMESTAMP(DATETIME "2008-12-25 15:30:00", "America/Los_Angeles") AS STRING) AS timestamp_datetime;

+------------------------+------------------------+------------------------+
| timestamp_str          | timestamp_date         | timestamp_datetime     |
+------------------------+------------------------+------------------------+
| 2008-12-25 23:30:00+00 | 2008-12-25 08:00:00+00 | 2008-12-25 23:30:00+00 |
+------------------------+------------------------+------------------------+

TIMESTAMP_ADD

TIMESTAMP_ADD(timestamp_expression, INTERVAL int64_expression date_part)

说明

向时间戳添加 int64_expression 单位的 date_part,不考虑任何时区。

TIMESTAMP_ADD 支持以下 date_part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR。等于 60 MINUTE

返回数据类型

TIMESTAMP

示例

SELECT
  TIMESTAMP "2008-12-25 15:30:00 UTC" as original,
  TIMESTAMP_ADD(TIMESTAMP "2008-12-25 15:30:00 UTC", INTERVAL 10 MINUTE) AS later;

+------------------------+------------------------+
| original               | later                  |
+------------------------+------------------------+
| 2008-12-25 15:30:00+00 | 2008-12-25 15:40:00+00 |
+------------------------+------------------------+

TIMESTAMP_SUB

TIMESTAMP_SUB(timestamp_expression, INTERVAL int64_expression date_part)

说明

从时间戳中减去 int64_expression 单位的 date_part,不考虑任何时区。

TIMESTAMP_SUB 支持以下 date_part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR。等于 60 MINUTE

返回数据类型

TIMESTAMP

示例

SELECT
  TIMESTAMP "2008-12-25 15:30:00 UTC" as original,
  TIMESTAMP_SUB(TIMESTAMP "2008-12-25 15:30:00 UTC", INTERVAL 10 MINUTE) AS earlier;

+------------------------+------------------------+
| original               | earlier                |
+------------------------+------------------------+
| 2008-12-25 15:30:00+00 | 2008-12-25 15:20:00+00 |
+------------------------+------------------------+

TIMESTAMP_DIFF

TIMESTAMP_DIFF(timestamp_expression, timestamp_expression, date_part)

说明

返回两个时间戳之间完整指定的 date_part 间隔数。第一个 timestamp_expression 代表较晚的日期;如果第一个 timestamp_expression 早于第二个 timestamp_expression,则输出为负值。如果计算结果溢出结果类型的精度(例如以纳秒表示的两个时间戳之间的差值溢出了 INT64 所能达到的精度),则会抛出一个错误。

TIMESTAMP_DIFF 支持以下 date_part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR。等于 60 MINUTE

返回数据类型

INT64

示例

SELECT
  TIMESTAMP "2010-07-07 10:20:00 UTC" as later_timestamp,
  TIMESTAMP "2008-12-25 15:30:00 UTC" as earlier_timestamp,
  TIMESTAMP_DIFF(TIMESTAMP "2010-07-07 10:20:00 UTC",
    TIMESTAMP "2008-12-25 15:30:00 UTC", HOUR) AS hours;

+------------------------+------------------------+-------+
| later_timestamp        | earlier_timestamp      | hours |
+------------------------+------------------------+-------+
| 2010-07-07 10:20:00+00 | 2008-12-25 15:30:00+00 | 13410 |
+------------------------+------------------------+-------+

在以下示例中,第一个时间戳出现在第二个时间戳之前,从而产生负输出。

SELECT TIMESTAMP_DIFF(TIMESTAMP "2018-08-14", TIMESTAMP "2018-10-14", DAY);

+---------------+
| negative_diff |
+---------------+
| -61           |
+---------------+

TIMESTAMP_TRUNC

TIMESTAMP_TRUNC(timestamp_expression, date_part[, time_zone])

说明

将时间戳截断到 date_part 的粒度。

TIMESTAMP_TRUNC 支持以下 date_part 值:

  • MICROSECOND
  • MILLISECOND
  • SECOND
  • MINUTE
  • HOUR
  • DAY
  • WEEK
  • WEEK(<WEEKDAY>): 将T timestamp_expression 截断到上一周的边界值,每周从 WEEKDAY 开始。WEEKDAY 的有效值包括 SUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAY
  • ISOWEEK:将 timestamp_expression 截断到上一个 ISO 8601 格式的周边界值。ISOWEEK 从星期一开始算起。每个 ISO 格式年份的第一个 ISOWEEK 都包含对应阳历年的第一个星期四。早于此日期的任何 date_expression 均会截断到上一个星期一。
  • MONTH
  • QUARTER
  • YEAR
  • ISOYEAR:将 timestamp_expression 截断到上一个 ISO 8601 格式的周编号年份边界值。ISO 格式年份的边界值是星期四属于相应公历年的第一周的星期一。

TIMESTAMP_TRUNC 函数支持可选的 time_zone 参数。此参数适用于以下 date_parts

  • MINUTE
  • HOUR
  • DAY
  • WEEK
  • WEEK(<WEEKDAY>)
  • MONTH
  • QUARTER
  • YEAR

如果您想要在截断操作过程中使用默认时区世界协调时间 (UTC) 以外的时区,请使用此参数。

TIMESTAMP 截断到 MINUTEHOUR 时,TIMESTAMP_TRUNC 会确定 TIMESTAMP 在指定(或默认)时区中的民用时间,并且从该 TIMESTAMP 中减去分钟和秒(截断到 HOUR 时)或减去秒(截断到 MINUTE 时)。虽然这在大多数情况下都可以提供直观的结果,但在临近夏令时转换时,小时并不一致,因此结果会不太直观。

返回数据类型

TIMESTAMP

示例

SELECT
  TIMESTAMP_TRUNC(TIMESTAMP '2008-12-25 15:30:00', DAY, 'UTC') as utc,
  TIMESTAMP_TRUNC(TIMESTAMP '2008-12-25 15:30:00', DAY, 'America/Los_Angeles') as la;

+------------------------+------------------------+
| utc                    | la                     |
+------------------------+------------------------+
| 2008-12-25 00:00:00+00 | 2008-12-25 08:00:00+00 |
+------------------------+------------------------+

在以下示例中,timestamp_expression 的时区偏移量为 +12。第一列显示世界协调时间 (UTC) 形式的 timestamp_expression。第二列使用从星期一开始的周显示 TIMESTAMP_TRUNC 输出。由于 timestamp_expression 在世界协调时间 (UTC) 中属于星期日,因此 TIMESTAMP_TRUNC 会将其截断到上一个星期一。第三列显示使用可选的时区定义参数 'Pacific/Auckland' 的相同函数。在这里,函数会根据新西兰夏令时截断 timestamp_expression,在这个时区内,它属于星期一。

SELECT
  timestamp,
  TIMESTAMP_TRUNC(timestamp, WEEK(MONDAY)) AS utc_truncated,
  TIMESTAMP_TRUNC(timestamp, WEEK(MONDAY), 'Pacific/Auckland') AS nzdt_truncated
FROM (SELECT TIMESTAMP('2017-11-06 00:00:00+12') AS timestamp);

+------------------------+------------------------+------------------------+
| timestamp              | utc_truncated          | nzdt_truncated         |
+------------------------+------------------------+------------------------+
| 2017-11-05 12:00:00+00 | 2017-10-30 07:00:00+00 | 2017-11-05 11:00:00+00 |
+------------------------+------------------------+------------------------+

在以下示例中,原始 timestamp_expression 是阳历年 2015 年。但对日期部分 ISOYEAR 执行 TIMESTAMP_TRUNC 会将 timestamp_expression 截断到 ISO 格式年份的开端,而非阳历年的开端。阳历年 2015 年的第一个星期四是 2015-01-01,因此 ISO 格式年份 2015 年开始于上一个星期一,也就是 2014-12-29。因此,timestamp_expression 2015-06-15 00:00:00+00 之前的 ISO 格式年份边界值是 2014-12-29。

SELECT
  TIMESTAMP_TRUNC('2015-06-15 00:00:00+00', ISOYEAR) AS isoyear_boundary,
  EXTRACT(ISOYEAR FROM TIMESTAMP '2015-06-15 00:00:00+00') AS isoyear_number;

+------------------------+----------------+
| isoyear_boundary       | isoyear_number |
+------------------------+----------------+
| 2014-12-29 00:00:00+00 | 2015           |
+------------------------+----------------+

FORMAT_TIMESTAMP

FORMAT_TIMESTAMP(format_string, timestamp[, time_zone])

说明

根据指定的 format_string 设置时间戳的格式。

如需查看此函数支持的格式元素列表,请参阅 TIMESTAMP 支持的格式元素

返回数据类型

STRING

示例

SELECT FORMAT_TIMESTAMP("%c", TIMESTAMP "2008-12-25 15:30:00", "America/Los_Angeles")
  AS formatted;

+--------------------------+
| formatted                |
+--------------------------+
| Thu Dec 25 07:30:00 2008 |
+--------------------------+

PARSE_TIMESTAMP

PARSE_TIMESTAMP(format_string, string[, time_zone])

说明

使用 format_string 和时间戳的字符串表示形式返回 TIMESTAMP 对象。

使用 PARSE_TIMESTAMP 时,请注意以下几点:

  • 未指定的字段。 任何未指定的字段均从 1970-01-01 00:00:00.0 开始初始化。此初始化值使用函数的时区参数(如果存在)所指定的时区。如果未提供此参数,则初始化值使用默认时区世界协调时间 (UTC)。例如,如果未指定年份,则默认为 1970,依此类推。
  • 不区分大小写的名称。 MondayFebruary 等名称不区分大小写。
  • 空格。 格式字符串中的一个或更多连续空格与时间戳字符串中的零个或更多连续空格相匹配。此外,始终可在时间戳字符串中使用前导空格和尾随空格(即使这些空格不在格式字符串中)。
  • 格式优先。 如果两个(或更多)格式元素的信息出现重叠(例如 %F%Y 均对年份有影响),则最后一个元素通常会替换前面的所有元素,但要注意存在一些例外情况(请参阅 %s%C%y 的说明)。

如需查看此函数支持的格式元素列表,请参阅 TIMESTAMP 支持的格式元素

返回数据类型

TIMESTAMP

示例

SELECT PARSE_TIMESTAMP("%c", "Thu Dec 25 07:30:00 2008", "America/Los_Angeles") as parsed;

+-------------------------+
| parsed                  |
+-------------------------+
| 2008-12-25 15:30:00 UTC |
+-------------------------+

TIMESTAMP_SECONDS

TIMESTAMP_SECONDS(int64_expression)

说明

int64_expression 解释为从 1970-01-01 00:00:00 UTC 开始计算的秒数。

返回数据类型

TIMESTAMP

示例

SELECT TIMESTAMP_SECONDS(1230219000) as timestamp;

+-------------------------+
| timestamp               |
+-------------------------+
| 2008-12-25 15:30:00 UTC |
+-------------------------+

TIMESTAMP_MILLIS

TIMESTAMP_MILLIS(int64_expression)

说明

int64_expression 解释为从 1970-01-01 00:00:00 UTC 开始计算的毫秒数。

返回数据类型

TIMESTAMP

示例

SELECT TIMESTAMP_MILLIS(1230219000000) as timestamp;

+-------------------------+
| timestamp               |
+-------------------------+
| 2008-12-25 15:30:00 UTC |
+-------------------------+

TIMESTAMP_MICROS

TIMESTAMP_MICROS(int64_expression)

说明

int64_expression 解释为从 1970-01-01 00:00:00 UTC 开始计算的微秒数。

返回数据类型

TIMESTAMP

示例

SELECT TIMESTAMP_MICROS(1230219000000000) as timestamp;

+-------------------------+
| timestamp               |
+-------------------------+
| 2008-12-25 15:30:00 UTC |
+-------------------------+

UNIX_SECONDS

UNIX_SECONDS(timestamp_expression)

说明

返回从 1970-01-01 00:00:00 UTC 开始计算的秒数。截断更高级别的精度。

返回数据类型

INT64

示例

SELECT UNIX_SECONDS(TIMESTAMP "2008-12-25 15:30:00") as seconds;

+------------+
| seconds    |
+------------+
| 1230219000 |
+------------+

UNIX_MILLIS

UNIX_MILLIS(timestamp_expression)

说明

返回从 1970-01-01 00:00:00 UTC 开始计算的毫秒数。截断更高级别的精度。

返回数据类型

INT64

示例

SELECT UNIX_MILLIS(TIMESTAMP "2008-12-25 15:30:00 UTC") as millis;

+---------------+
| millis        |
+---------------+
| 1230219000000 |
+---------------+

UNIX_MICROS

UNIX_MICROS(timestamp_expression)

说明

返回从 1970-01-01 00:00:00 UTC 开始计算的微秒数。截断更高级别的精度。

返回数据类型

INT64

示例

SELECT UNIX_MICROS(TIMESTAMP "2008-12-25 15:30:00") as micros;

+------------------+
| micros           |
+------------------+
| 1230219000000000 |
+------------------+

TIMESTAMP 支持的格式元素

除非另有说明,否则使用格式字符串的 TIMESTAMP 函数均支持以下元素:

格式元素 说明
%A 星期几的全名。
%a 星期几的缩写名称。
%B 月份的全名。
%b 或 %h 月份的缩写名称。
%C 用十进制数 (00-99) 表示的世纪(年份除以 100 并截断为整数)。
%c 表示日期和时间。
%D 采用 %m/%d/%y 格式的日期。
%d 用十进制数 (01-31) 表示的月份中的某一天。
%e 用十进制数 (1-31) 表示的月份中的某一天;个位数前面附加一个空格。
%F 采用 %Y-%m-%d 格式的日期。
%G 用十进制数表示的四位数的 ISO 8601 格式年份。每个 ISO 格式年份开始于公历年的第一个星期四之前的星期一。请注意,%G 和 %Y 可能会在公历年边界值附近产生不同的结果,其中公历年和 ISO 格式年份可能会有所不同。
%g 用十进制数 (00-99) 表示的两位数的 ISO 8601 格式年份。每个 ISO 格式年份开始于公历年的第一个星期四之前的星期一。请注意,%G 和 %Y 可能会在公历年边界值附近产生不同的结果,其中公历年和 ISO 格式年份可能会有所不同。
%H 用十进制数 (00-23) 表示的小时数(24 小时制)。
%I 用十进制数 (01-12) 表示的小时数(12 小时制)。
%j 用十进制数 (001-366) 表示的一年中的某一天。
%k 用十进制数 (0-23) 表示的小时数(24 小时制);个位数前面附加一个空格。
%l 用十进制数 (1-12) 表示的小时数(12 小时制);个位数前面附加一个空格。
%M 用十进制数 (00-59) 表示的分钟数。
%m 用十进制数 (01-12) 表示的月份。
%n 换行符。
%P am 或 pm。
%p AM 或 PM。
%R 采用 %H:%M 格式显示的时间。
%r 使用 AM/PM 标记法表示的 12 小时制的时间。
%S 用十进制数 (00-60) 表示的秒数。
%s 从 1970-01-01 00:00:00 UTC 开始计算的秒数。无论 %s 出现在字符串的哪个位置,始终替换所有其他格式元素。如果出现多个 %s 元素,则以最后一个元素为准。
%T 采用 %H:%M:%S 格式表示的时间。
%t 制表符。
%U 用十进制数 (00-53) 表示的一年中的周数(星期日算作一周的第一天)。
%u 用十进制数 (1-7) 表示的星期名称(星期一算作一周的第一天)。
%V 用十进制数 (01-53) 表示的一年中的周数(星期一算作一周的第一天)。如果包含 1 月 1 日的那一周有 4 天或超过 4 天属于新的一年,则该周为第 1 周;否则为上一年的第 53 周,而下一周为第 1 周。
%W 用十进制数 (00-53) 表示的一年的周数(星期一算作一周的第一天)。
%w 用十进制数 (0-6) 表示的星期名称(星期日算作一周的第一天)。
%X 采用 HH:MM:SS 格式表示的时间。
%x 采用 MM/DD/YY 格式表示的日期。
%Y 用十进制数表示的四位数的年份。
%y 用十进制数 (00-99) 表示的后两位数的年份,前导零可选填。可与 %C 混用。如果未指定 %C,则 00-68 年为 2000 年代,而 69-99 年为 1900 年代。
%Z 时区名称。
%z 根据情况采用 +HHMM 或 -HHMM 格式表示与本初子午线的偏移量,其中正值表示格林威治东区。
%% 单个 % 字符。
%Ez 与 RFC 3339 兼容的数字时区(+HH:MM 或 -HH:MM)。
%E#S 具有 # 位小数精度的秒数。
%E*S 具有完整小数精度的秒数(字面量“*”)。
%E4Y 四个字符的年份 (0001 ... 9999)。注意:%Y 将生成尽量多的字符数以完整显示年份。

时区定义

某些日期和时间戳函数可用于替换默认时区并指定其他时区。您可采用以下格式提供其世界协调时间 (UTC) 偏移量,从而指定一个时区:

(+|-)H[H][:M[M]]

例如:

-08:00

地理位置函数

地理位置函数用于生成 BigQuery GEOGRAPHY 值或对其进行操作。任何地理位置函数的名称均以 ST_ 开头。BigQuery 支持以下函数,这些函数可用于分析地理数据、确定地貌之间的空间关系,以及构造或操作 GEOGRAPHY

地理位置函数根据其行为分为以下类别:

如果任何输入参数为 NULL,则所有 BigQuery 地理位置函数均返回 NULL

ST_GEOGPOINT

ST_GEOGPOINT(longitude, latitude)

说明

创建包含一个点的 GEOGRAPHYST_GEOGPOINT 根据指定的 FLOAT64 格式的经度和纬度参数创建一个点,并通过 GEOGRAPHY 值返回该点。

限制条件

  • 纬度必须在 [-90, 90] 范围内。超出此范围的纬度将导致错误。
  • 允许超出 [-180,180] 范围的经度;ST_GEOGPOINT 使用输入经度对 360 取模的余数来获得 [-180, 180] 范围内的经度。

返回类型

GEOGRAPHY

ST_MAKELINE

ST_MAKELINE(geography_1, geography_2)
ST_MAKELINE(array_of_geography)

说明

通过单个线串(表示一系列点和连接这些点的线段)创建 GEOGRAPHY,方法是按输入顺序连接每个输入 GEOGRAPHY 的点或线段顶点。

ST_MAKELINE 有两种变体。对于第一种变体,输入必须是两个 GEOGRAPHY。对于第二种变体,输入必须是 GEOGRAPHY 类型的 ARRAY。在任一变体中,每个输入 GEOGRAPHY 都必须只包含下列值之一:

  • 一个点。
  • 一个线串。

对于 ST_MAKELINE 的第一种变体,如果输入 GEOGRAPHYNULL,则 ST_MAKELINE 返回 NULL。对于第二种变体,如果输入 ARRAY 或输入 ARRAY 中的任何元素是 NULL,则 ST_MAKELINE 返回 NULL

限制条件

每条边的跨度必须严格小于 180 度。

注意:BigQuery 的贴靠过程可能会舍弃过于短的边并将两个端点贴靠在一起。例如,如果两个输入 GEOGRAPHY 各自包含一个点,并且两个点之间的距离小于贴靠半径,则这两个点将被贴靠在一起。在这种情况下,返回结果为只有一个点的 GEOGRAPHY

返回类型

GEOGRAPHY

ST_MAKEPOLYGON

ST_MAKEPOLYGON(geography_expression)
ST_MAKEPOLYGON(geography_expression, array_of_geography)

说明

创建一个包含由线串输入组成的单个多边形的 GEOGRAPHY,其中每个输入线串用于构造多边形的环。

ST_MAKEPOLYOGN 有两种变体。对于第一种变体,输入线串由仅包含一个线串的单个 GEOGRAPHY 提供。对于第二种变体,输入由单个 GEOGRAPHY 和一个 GEOGRAPHY 数组构成,其中每个 GEOGRAPHY 都只包含一个线串。两种变体中的第一个 GEOGRAPHY 用于构造多边形的外环。输入 ARRAY 所提供的其他 GEOGRAPHY 则用于指定多边形内环。每个只包含一个线串的输入 GEOGRAPHY 必须满足以下条件:

  • 线串必须至少包含三个不同的顶点。
  • 线串必须闭合:也就是说,第一个顶点和最后一个顶点必须为同一顶点。如果第一个顶点和最后一个顶点不同,则该函数会为第一个顶点和最后一个顶点构造一条边。

对于 ST_MAKEPOLYGON 的第一种变体,如果任一输入 GEOGRAPHYNULL,则 ST_MAKEPOLYOGN 返回 NULL。对于第二种变体,如果输入 ARRAYARRAY 中的任何元素是 NULL,则 ST_MAKEPOLYGON 返回 NULL

注意:ST_MAKEPOLYGON 接受空的 GEOGRAPHY 作为输入。ST_MAKEPOLYGON 将空的 GEOGRAPHY 解释为具有空的线串,这将创建一个完整的环:即覆盖整个地球的多边形。

限制条件

输入环必须组成一个有效的多边形:

  • 每个多边形内环都必须处于多边形外环内。
  • 多边形只能有一个外环(必须是第一个输入环)。这意味着多边形内环不能嵌套。
  • 多边形环只能在两个环的边界的顶点处相交。

每条边的跨度必须严格小于 180 度。

每个多边形环会将球面分成两个区域。ST_MAKEPOLYGON 的第一个输入线串构成多边形外环,其内部是两个区域中较小的区域。每个后续输入线串可指定一个多边形内环,它为多边形内部进行了良好的定义。如需定义一个多边形外环,使多边形内部区域是这两个区域中较大的区域,请参阅 ST_MAKEPOLYGONORIENTED

注意:BigQuery 的贴靠过程可能会舍弃过于短的边并将两个端点贴靠在一起。因此,当顶点贴靠在一起时,特别小的多边形内环可能会消失,或者输出 GEOGRAPHY 可能只包含一条线段或一个点。

返回类型

GEOGRAPHY

ST_MAKEPOLYGONORIENTED

ST_MAKEPOLYGONORIENTED(array_of_geography)

说明

ST_MAKEPOLYGON 大体一样,但每个输入线串的顶点顺序决定了每个多边形环的方向。多边形环的方向按如下方式定义多边形的内部:如果按照输入顶点的顺序沿多边形的边界前进,则多边形的内部位于左侧。这适用于每个给定的多边形环。

作为多边形构造函数的变体,ST_MAKEPOLYGONORIENTED 更加灵活,因为它能够构造一个内部区域可位于环的任意一侧的多边形。总之,多边形环的正确方向对于构造所需的多边形而言至关重要。

如果输入 ARRAYARRAY 中的任何元素是 NULL,则 ST_MAKEPOLYGONORIENTED 返回 NULL

注意:ST_MAKEPOLYGONORIENTED 的输入参数可能包含空的 GEOGRAPHYST_MAKEPOLYGONORIENTED 将空的 GEOGRAPHY 解释为具有空线串,这将创建一个完整的环,即覆盖整个地球的多边形。

限制条件

输入环必须组成一个有效的多边形:

  • 每个多边形内环都必须处于多边形外环内。
  • 多边形只能有一个外环(必须是第一个输入环)。这意味着多边形内环不能嵌套。
  • 多边形环只能在两个环的边界的顶点处相交。

每条边的跨度必须严格小于 180 度。

ST_MAKEPOLYGONORIENTED 根据每个线串的输入顶点的顺序来确定多边形的方向。这适用于多边形外环和任意内环。ST_MAKEPOLYGONORIENTED 构建的多边形的所有内环均与外环方向相反。如需了解其他多边形构造函数以及构建有效多边形的其他限制条件,请参阅 ST_MAKEPOLYGON

注意:BigQuery 的贴靠过程可能会舍弃长度过短的边并将两个端点贴靠在一起,使其成为一个点。因此,线串中的顶点可能会被贴靠在一起,造成一条或多条边消失。因此,特别小的多边形内环可能会消失,或者输出 GEOGRAPHY 可能只包含一条线段或一个点。

返回类型

GEOGRAPHY

ST_GEOGFROMGEOJSON

ST_GEOGFROMGEOJSON(geojson_string)

说明

返回与输入 GeoJSON 表示形式相对应的 GEOGRAPHY 值。

ST_GEOGFROMGEOJSON 接受遵循 RFC 7946 的输入。

BigQuery GEOGRAPHY 具有球面测地边,而 GeoJSON Geometry 对象明确具有平面边。为了在这两种边之间进行转换,BigQuery 会在必要时为线段添加其他点,以使转换后的边序列保持在原始边的 10 米范围内。

要将 GEOGRAPHY 的格式设置为 GeoJSON,请参阅 ST_ASGEOJSON

限制条件

输入存在以下限制条件:

  • ST_GEOGFROMGEOJSON 只接受 JSON 几何图形片段,不能用于提取整个 JSON 文档。
  • 输入 JSON 片段必须包含 GeoJSON 几何图形类型,包括 PointMultiPointLineStringMultiLineStringPolygonMultiPolygonGeometryCollection。其他任何 GeoJSON 类型都将导致出错,例如 FeatureFeatureCollection
  • GeoJSON 几何图形类型的 coordinates 成员的位置信息必须由两个元素组成。第一个是经度,第二个是纬度。因此,ST_GEOGFROMGEOJSON 不支持 coordinates 成员的位置信息包含可选的第三个元素。

返回类型

GEOGRAPHY

ST_GEOGFROMTEXT

ST_GEOGFROMTEXT(wkt_string)
ST_GEOGFROMTEXT(wkt_string, oriented)

说明

返回与输入 WKT 表示形式相对应的 GEOGRAPHY 值。

此函数支持为 oriented 设置 BOOL 类型的可选参数。如果此参数设置为 TRUE,则由输入构成的多边形按以下方式确定方向:如果按照输入顶点的顺序沿多边形的边界前进,则多边形的内部位于左侧。这使得 WKT 能够表示大于半球的多边形。如果 orientedFALSE 或省略,则此函数返回面积较小的多边形。另请参阅 ST_MAKEPOLYGONORIENTED,此函数与 ST_GEOGFROMTEXT 类似,但 oriented=TRUE

要将 GEOGRAPHY 的格式设置为 WKT,请使用 ST_ASTEXT

限制条件

所有输入边均假定为球面测地线,而不是平面直线。如需读取平面投影中的数据,请考虑使用 ST_GEOGFROMGEOJSON。如需详细了解球面测地线和平面线之间的差异,请参阅坐标系和边

返回类型

GEOGRAPHY

示例

以下查询读取 WKT 字符串 POLYGON((0 0, 0 2, 2 2, 0 2, 0 0)),结果同时包含非定向多边形和定向多边形,然后检查每个结果是否包含点 (1, 1)

WITH polygon AS (SELECT 'Polygon((0 0, 0 2, 2 2, 2 0, 0 0))' AS p)
SELECT
  ST_CONTAINS(ST_GEOGFROMTEXT(p), ST_GEOGPOINT(1, 1)) AS fromtext_default,
  ST_CONTAINS(ST_GEOGFROMTEXT(p, FALSE), ST_GEOGPOINT(1, 1)) AS non_oriented,
  ST_CONTAINS(ST_GEOGFROMTEXT(p, TRUE),  ST_GEOGPOINT(1, 1)) AS oriented
FROM polygon;

+-------------------+---------------+-----------+
| fromtext_default  | non_oriented  | oriented  |
+-------------------+---------------+-----------+
| true              | true          | false     |
+-------------------+---------------+-----------+

ST_GEOGFROMWKB

ST_GEOGFROMWKB(wkb_bytes)

说明

返回与输入 WKB 表示形式对应的 GEOGRAPHY 值。

要将 GEOGRAPHY 的格式设置为 WKB,请使用 ST_ASBINARY

限制条件

所有输入边均假定为球面测地线,而不是平面直线。如需读取平面投影中的数据,请考虑使用 ST_GEOGFROMGEOJSON

返回类型

GEOGRAPHY

ST_GEOGPOINTFROMGEOHASH

ST_STGEOGPOINTFROMGEOHASH(geohash)

说明

返回与 GeoHash 中定义的边界框的中间点对应的 GEOGRAPHY 值。

返回类型

GEOGRAPHY

ST_ASGEOJSON

ST_ASGEOJSON(geography_expression)

说明

为输入 GEOGRAPHY 返回遵循 RFC 7946GeoJSON 表示形式。

BigQuery GEOGRAPHY 具有球面测地边,而 GeoJSON Geometry 对象明确具有平面边。为了在这两种边之间进行转换,BigQuery 会在必要时为线段添加其他点,以使转换后的边序列保持在原始边的 10 米范围内。

要利用 GeoJSON 构造 GEOGRAPHY,请参阅 ST_GEOGFROMGEOJSON

返回类型

STRING

ST_ASTEXT

ST_ASTEXT(geography_expression)

说明

返回输入 GEOGRAPHYWKT 表示形式。

要利用 WKT 构造 GEOGRAPHY,请参阅 ST_GEOGFROMTEXT

返回类型

STRING

ST_GEOHASH

ST_GEOHASH(geography_expression, maxchars)

说明

返回 geography_expressionGeoHash 表示形式。生成的 GeoHash 最多包含 maxchars 个字符。较少的字符对应较低的精确度(换句话说,其边界框较大)。

ST_GeoHash 会为空的 GEOGRAPHY 对象返回 NULL

限制条件

  • 仅支持表示一个点的 GEOGRAPHY 对象。
  • maxchars 的最大值为 20。

示例

返回西雅图中心的 GeoHash 表示形式,精确度为 10 个字符。

SELECT ST_GEOHASH(ST_GEOGPOINT(-122.35, 47.62), 10) geohash

+--------------+
| geohash      |
+--------------+
| c22yzugqw7   |
+--------------+

返回类型

STRING

ST_ASBINARY

ST_ASBINARY(geography_expression)

说明

返回输入 GEOGRAPHYWKB 表示形式。

要利用 WKB 构造 GEOGRAPHY,请参阅 ST_GEOGFROMWKB

返回类型

BYTES

ST_BOUNDARY

ST_BOUNDARY(geography_expression)

说明

返回一个 GEOGRAPHY,其中包含给定输入 GEOGRAPHY 中每个组成部分边界的并集。

GEOGRAPHY 的每个组成部分边界的定义如下:

  • 点的边界为空。
  • 线串的边界由线串的端点组成。
  • 多边形的边界由构成多边形外环及其所有内环的线串组成。

返回类型

GEOGRAPHY

ST_CENTROID

ST_CENTROID(geography_expression)

说明

以单点 GEOGRAPHY 的形式返回输入 GEOGRAPHY 的形心

GEOGRAPHY 的形心表示 GEOGRAPHY 的最高维组成部分的形心的加权平均值。每个维度组成部分的形心如下定义:

  • 点的形心是输入坐标的算术平均值。
  • 线串的形心是所有边按长度加权的形心。每条边的形心是其测地线中点。
  • 多边形的形心是其质心。

如果输入 GEOGRAPHY 为空,则返回空的 GEOGRAPHY

限制条件

如果 GEOGRAPHY 的形心无法由地球表面上的某个点定义,则返回具备确定性的任意点。只有当形心恰好位于地球中心时才会发生这种情况,例如一对对映点的形心,这种可能性非常小。

返回类型

GEOGRAPHY

ST_CLOSESTPOINT

ST_CLOSESTPOINT(geography_1, geography_2)
ST_CLOSESTPOINT(geography_1, geography_2, use_spheroid)

说明

返回一个 GEOGRAPHY,其中包含 geography_1 上与 geography_2 距离最小的点。这意味着,ST_CLOSESTPOINT 返回的点与 geography_2 之间的距离小于或等于 geography_1 上的任何其它点与 geography_2 之间的距离。

如果任一输入 GEOGRAPHY 为空,则 ST_CLOSESTPOINT 返回 NULL

可选的 use_spheroid 参数用于确定此函数计算距离的方式。如果 use_spheroidFALSE,则此函数计算完美球面上的距离。

use_spheroid 参数目前仅支持值 FALSEuse_spheroid 的默认值为 FALSE

返回类型

GEOGRAPHY

ST_DIFFERENCE

ST_DIFFERENCE(geography_1, geography_2)

说明

返回表示 geography_1geography_2 的点集差异的 GEOGRAPHY

如果 geometry_1 完全包含在 geometry_2 内,则 ST_DIFFERENCE 返回空的 GEOGRAPHY

限制条件

BigQuery GEOGRAPHY 表示的基础几何图形对象对应于点集的闭集。因此,ST_DIFFERENCEgeography_1geography_2 的点集差异的闭集。这意味着如果 geography_1geography_2 相交,则其点集差异可能包含 geography_2 的边界的一部分。

返回类型

GEOGRAPHY

ST_INTERSECTION

ST_INTERSECTION(geography_1, geography_2)

说明

返回表示两个输入 GEOGRAPHY 的点集的交集的 GEOGRAPHY。也就是说,交集部分中的每个点均出现在 geography_1geography_2 中。

如果两个输入 GEOGRAPHY 不相交,即输入 geometry_1geometry_2 不存在公共点,则返回空的 GEOGRAPHY

如需了解相关的谓词函数,请参阅 ST_INTERSECTSST_DISJOINT

返回类型

GEOGRAPHY

ST_SNAPTOGRID

ST_SNAPTOGRID(geography_expression, grid_size)

说明

返回输入 GEOGRAPHY,其中每个顶点均已贴靠到经度/纬度网格。网格大小由 grid_size 参数确定,此参数以度为单位。

限制条件

不支持任意的网格大小。grid_size 参数采用四舍五入来计算,因此其格式为 $$10^n$$,其中 $$-10 < n < 0$$。

返回类型

GEOGRAPHY

ST_UNION

ST_UNION(geography_1, geography_2)
ST_UNION(array_of_geography)

说明

返回表示所有输入 GEOGRAPHY 的点集的并集的 GEOGRAPHY

ST_UNION 有两种变体。对于第一种变体,输入必须是两个 GEOGRAPHY。对于第二种变体,输入是 GEOGRAPHY 类型的 ARRAY

对于 ST_UNION 的第一种变体,如果输入 GEOGRAPHYNULL,则 ST_UNION 返回 NULL。对于第二种变体,如果输入 ARRAY 值为 NULL,则 ST_UNION 返回 NULL。对于非 NULL 的输入 ARRAY,系统将计算并集,并忽略 NULL 元素,使得它们不会影响输出。

如需了解 ST_UNION 的聚合版本,请参阅 ST_UNION_AGG

返回类型

GEOGRAPHY

ST_X

ST_X(geography_expression)

说明

返回单点输入 GEOGRAPHY 的经度,以度为单位。

对于任何非单点输入的 GEOGRAPHY,包括空的 GEOGRAPHYST_X 会返回一个错误。使用 SAFE. 前缀时,此函数返回 NULL

返回类型

FLOAT64

示例

以下示例使用 ST_XST_Y 从单点地理位置提取坐标。

WITH points AS
   (SELECT ST_GEOGPOINT(i, i + 1) AS p FROM UNNEST([0, 5, 12]) AS i)
 SELECT
   p,
   ST_X(p) as longitude,
   ST_Y(p) as latitude
FROM points;

+--------------+-----------+----------+
| p            | longitude | latitude |
+--------------+-----------+----------+
| POINT(0 1)   | 0.0       | 1.0      |
| POINT(5 6)   | 5.0       | 6.0      |
| POINT(12 13) | 12.0      | 13.0     |
+--------------+-----------+----------+

ST_Y

ST_Y(geography_expression)

说明

返回单点输入 GEOGRAPHY 的纬度,以度为单位。

对于任何非单点输入的 GEOGRAPHY,包括空的 GEOGRAPHYST_Y 会返回一个错误。使用 SAFE. 前缀时,此函数返回 NULL

返回类型

FLOAT64

示例

如需查看使用示例,请参阅 ST_X

ST_CONTAINS

ST_CONTAINS(geography_1, geography_2)

说明

如果 geography_2 中没有位于 geography_1 外部的点,并且二者内部相交,则返回 TRUE;否则返回 FALSE

注意:GEOGRAPHY包含自己的边界。与 ST_COVERS 进行比较。

返回类型

BOOL

示例

以下查询测试多边形 POLYGON((1 1, 20 1, 10 20, 1 1)) 是否包含 (0, 0)(1, 1)(10, 10),这三个点分别位于多边形的外部、边界和内部。

SELECT
  ST_GEOGPOINT(i, i) AS p,
  ST_CONTAINS(ST_GEOGFROMTEXT('POLYGON((1 1, 20 1, 10 20, 1 1))'),
              ST_GEOGPOINT(i, i)) AS `contains`
FROM UNNEST([0, 1, 10]) AS i;

+--------------+----------+
| p            | contains |
+--------------+----------+
| POINT(0 0)   | false    |
| POINT(1 1)   | false    |
| POINT(10 10) | true     |
+--------------+----------+

ST_COVEREDBY

ST_COVEREDBY(geography_1, geography_2)

说明

如果 geography_1geography_2 为空,则返回 FALSE。如果 geography_1 中没有位于 geography_2 外部的点,则返回 TRUE

对于给定的两个 GEOGRAPHYabST_COVEREDBY(a, b) 会返回与 ST_COVERS(b, a) 相同的结果。注意参数的顺序相反。

返回类型

BOOL

ST_COVERS

ST_COVERS(geography_1, geography_2)

说明

如果 geography_1geography_2 为空,则返回 FALSE。如果 geography_2 中没有位于 geography_1 外部的点,则返回 TRUE

返回类型

BOOL

示例

以下查询测试多边形 POLYGON((1 1, 20 1, 10 20, 1 1)) 是否覆盖 (0, 0)(1, 1)(10, 10),这三个点分别位于多边形的外部、边界和内部。

SELECT
  ST_GEOGPOINT(i, i) AS p,
  ST_COVERS(ST_GEOGFROMTEXT('POLYGON((1 1, 20 1, 10 20, 1 1))'),
            ST_GEOGPOINT(i, i)) AS `covers`
FROM UNNEST([0, 1, 10]) AS i;

+--------------+--------+
| p            | covers |
+--------------+--------+
| POINT(0 0)   | false  |
| POINT(1 1)   | true   |
| POINT(10 10) | true   |
+--------------+--------+

ST_DISJOINT

ST_DISJOINT(geography_1, geography_2)

说明

如果 geography_1geography_2 的交集为空,则返回 TRUE,也就是说,geography_1 中没有同时位于 geography_2 中的点。

ST_DISJOINTST_INTERSECTS 的逻辑求反函数。

返回类型

GEOGRAPHY

ST_DWITHIN

ST_DWITHIN(geography_1, geography_2), distance)
ST_DWITHIN(geography_1, geography_2, distance, use_spheroid)

说明

如果 geography_1 中至少有一个点与 geography_2 中的一个点的距离小于或等于给定 distance 参数的距离,则返回 TRUE;否则,返回 FALSE。如果任一输入 GEOGRAPHY 为空,则 ST_DWithin 返回 FALSE。给定 distance 为地球表面以米为单位的距离。

可选的 use_spheroid 参数用于确定此函数计算距离的方式。如果 use_spheroidFALSE,则此函数计算完美球面上的距离。

use_spheroid 参数目前仅支持值 FALSEuse_spheroid 的默认值为 FALSE

返回类型

BOOL

ST_EQUALS

ST_EQUALS(geography_1, geography_2)

说明

如果 geography_1geography_2 代表相同的 GEOGRAPHY 值,则返回 TRUE。更确切地说,这意味着必须满足以下条件之一:

  • ST_COVERS(geography_1, geography_2) = TRUEST_COVERS(geography_2, geography_1) = TRUE
  • geography_1geography_2 均为空。

因此,即使两个 GEOGRAPHY 的点或顶点的顺序不同,只要其仍然代表相同的几何结构,二者就可能相等。

限制条件

ST_EQUALS 不保证其为传递函数。

返回类型

BOOL

ST_INTERSECTS

ST_INTERSECTS(geography_1, geography_2)

说明

如果 geography_1geography_2 的点集的交集非空,则返回 TRUE。也就是说,如果两个输入 GEOGRAPHY 至少有一个公共点,则此函数返回 TRUE

如果 ST_INTERSECTS 返回 TRUE,则表示 ST_DISJOINT 会返回 FALSE

返回类型

BOOL

ST_INTERSECTSBOX

ST_INTERSECTSBOX(geography, lng1, lat1, lng2, lat2)

说明

如果 geography[lng1, lng2][lat1, lat2] 所形成的矩形相交,则返回 TRUE。矩形的边由经度和纬度的恒定线组成。lng1lng2 指定矩形边界的最小和最大经度线,lat1lat2 指定矩形边界的最小和最大恒定纬度线。

指定所有经度和纬度参数时,以度为单位。

限制条件

输入参数存在以下限制条件:

  • 纬度应在 [-90, 90] 度范围内。
  • 经度应在 [-180, 180] 度范围内。

返回类型

BOOL

ST_TOUCHES

ST_TOUCHES(geography_1, geography_2)

说明

如果满足以下两个条件,则返回 TRUE

  1. geography_1geography_2 相交。
  2. geography_1 的内部和 geography_2 的内部不相交。

返回类型

BOOL

ST_WITHIN

ST_WITHIN(geography_1, geography_2)

说明

如果 geography_1 中没有位于 geography_2 外部的点,且 geography_1geography_2 的内部相交,则返回 TRUE

对于给定的两个地理位置 abST_WITHIN(a, b) 会返回与 ST_CONTAINS(b, a) 相同的结果。注意参数的顺序相反。

返回类型

BOOL

ST_ISEMPTY

ST_ISEMPTY(geography_expression)

说明

如果给定 GEOGRAPHY 为空,则返回 TRUE;也就是说,GEOGRAPHY 不包含任何点、线段或多边形。

注意:BigQuery 中的空 GEOGRAPHY 与特定的几何形状无关。例如,表达式 ST_GEOGFROMTEXT('POINT EMPTY')ST_GEOGFROMTEXT('GEOMETRYCOLLECTION EMPTY') 的返回结果是相同的。

返回类型

BOOL

ST_ISCOLLECTION

ST_ISCOLLECTION(geography_expression)

说明

如果点、线串和多边形的总数大于 1,则返回 TRUE

空的 GEOGRAPHY 不是集合。

返回类型

BOOL

ST_DIMENSION

ST_DIMENSION(geography_expression)

说明

返回输入 GEOGRAPHY 中最高维元素的维度。

每个可能元素的维度如下:

  • 点的维度为 0
  • 线串的维度为 1
  • 多边形的维度为 2

如果输入 GEOGRAPHY 为空,则 ST_DIMENSION 返回 -1

返回类型

INT64

ST_NUMPOINTS

ST_NUMPOINTS(geography_expression)

说明

返回输入 GEOGRAPHY 的顶点数。这包括点的数量、线串顶点的数量以及多边形顶点的数量。

注意:多边形环的第一个顶点和最后一个顶点按不同顶点计算。

返回类型

INT64

ST_AREA

ST_AREA(geography_expression)
ST_AREA(geography_expression, use_spheroid)

说明

返回输入 GEOGRAPHY 中的多边形覆盖的面积(以平方米为单位)。

如果 geography_expression 是一个点或一条线段,则返回零。如果 geography_expression 是一个集合,则返回集合中多边形覆盖的面积;如果此集合不包含多边形,则返回零。

可选的 use_spheroid 参数用于确定此函数计算距离的方式。如果 use_spheroidFALSE,则此函数计算完美球面上的距离。

use_spheroid 参数目前仅支持值 FALSEuse_spheroid 的默认值为 FALSE

返回类型

FLOAT64

ST_DISTANCE

ST_DISTANCE(geography_1, geography_2)
ST_DISTANCE(geography_1, geography_2, use_spheroid)

说明

返回两个非空 GEOGRAPHY 之间的最短距离(以米为单位)。

如果任一输入 GEOGRAPHY 为空,则 ST_DISTANCE 返回 NULL

可选的 use_spheroid 参数用于确定此函数计算距离的方式。如果 use_spheroidFALSE,则此函数计算完美球面上的距离。

use_spheroid 参数目前仅支持值 FALSEuse_spheroid 的默认值为 FALSE

返回类型

FLOAT64

ST_LENGTH

ST_LENGTH(geography_expression)
ST_LENGTH(geography_expression, use_spheroid)

说明

返回输入 GEOGRAPHY 中线段的总长度(以米为单位)。

如果 geography_expression 是点或多边形,则返回零。如果 geography_expression 是一个集合,则返回集合中线段的长度;如果此集合不包含线段,则返回零。

可选的 use_spheroid 参数用于确定此函数计算距离的方式。如果 use_spheroidFALSE,则此函数计算完美球面上的距离。

use_spheroid 参数目前仅支持值 FALSEuse_spheroid 的默认值为 FALSE

返回类型

FLOAT64

ST_MAXDISTANCE

ST_MAXDISTANCE(geography_1, geography_2)
ST_MAXDISTANCE(geography_1, geography_2, use_spheroid)

返回两个非空 GEOGRAPHY 之间的最长距离(以米为单位);也就是返回第一个 GEOGRAPHY 中的一个顶点和第二个 GEOGRAPHY 中的一个顶点之间的距离。如果 geography_1geography_2 是同一个 GEOGRAPHY,则此函数返回这个 GEOGRAPHY 中最远的两个顶点之间的距离。

如果任一输入 GEOGRAPHY 为空,则 ST_MAXDISTANCE 返回 NULL

可选的 use_spheroid 参数用于确定此函数计算距离的方式。如果 use_spheroidFALSE,则此函数计算完美球面上的距离。

use_spheroid 参数目前仅支持值 FALSEuse_spheroid 的默认值为 FALSE

返回类型

FLOAT64

ST_PERIMETER

ST_PERIMETER(geography_expression)
ST_PERIMETER(geography_expression, use_spheroid)

说明

返回输入 GEOGRAPHY 中的多边形的边界长度(以米为单位)。

如果 geography_expression 是一个点或一条线段,则返回零。如果 geography_expression 是一个集合,则返回集合中多边形的周长;如果此集合不包含多边形,则返回零。

可选的 use_spheroid 参数用于确定此函数计算距离的方式。如果 use_spheroidFALSE,则此函数计算完美球面上的距离。

use_spheroid 参数目前仅支持值 FALSEuse_spheroid 的默认值为 FALSE

返回类型

FLOAT64

ST_UNION_AGG

ST_UNION_AGG(geography)

说明

返回表示所有输入 GEOGRAPHY 的点集的并集的 GEOGRAPHY

ST_UNION_AGG 会忽略输入 NULLGEOGRAPHY 值。

如需查看 ST_UNION_AGG 的非聚合版本,请参阅 ST_UNION

返回类型

GEOGRAPHY

ST_CENTROID_AGG

ST_CENTROID_AGG(geography)

说明

计算一组输入 GEOGRAPHY 的形心,并返回单点 GEOGRAPHY

一组输入 GEOGRAPHY 的形心表示每个单独 GEOGRAPHY 的形心的加权平均值。在一组输入中,只有具有最高维度的 GEOGRAPHY 会影响整组输入的形心。例如,如果输入中包括含有线段的 GEOGRAPHY 和仅含有点的 GEOGRAPHY,则 ST_CENTROID_AGG 会返回含有线段的 GEOGRAPHY 的加权平均值,因为它们具有最高维度。在此示例中,ST_CENTROID_AGG 在计算聚合形心时忽略仅含有点的 GEOGRAPHY

ST_CENTROID_AGG 会忽略输入 NULLGEOGRAPHY 值。

如需查看 ST_CENTROID_AGG 的非聚合版本以及单个 GEOGRAPHY 值的形心的定义,请参阅 ST_CENTROID

返回类型

GEOGRAPHY

示例

以下查询计算一组 GEOGRAPHY 值的聚合形心。第一个查询的输入仅包含点,因此每个值都会影响聚合形心。另请注意,ST_CENTROID_AGG 并不等同于对 ST_UNION_AGG 的结果调用 ST_CENTROID;计算并集的函数会移除重复项,而这与 ST_CENTROID_AGG 不同。第二个查询的输入具有混合维度,其中只有具有最高维度的值(线段)才会影响聚合形心。

SELECT ST_CENTROID_AGG(points) AS st_centroid_agg,
ST_CENTROID(ST_UNION_AGG(points)) AS centroid_of_union
FROM UNNEST([ST_GEOGPOINT(1, 5),
             ST_GEOGPOINT(1, 2),
             ST_GEOGPOINT(1, -1),
             ST_GEOGPOINT(1, -1)]) points;

+---------------------------+-------------------+
| st_centroid_agg           | centroid_of_union |
+---------------------------+-------------------+
| POINT(1 1.24961422620969) | POINT(1 2)        |
+---------------------------+-------------------+

SELECT ST_CENTROID_AGG(points) AS st_centroid_agg
FROM UNNEST([ST_GEOGPOINT(50, 26),
             ST_GEOGPOINT(34, 33.3),
             ST_GEOGFROMTEXT('LINESTRING(0 -1, 0 1)')
             ST_GEOGFROMTEXT('LINESTRING(0 1, 0 3)')]) points;

+-----------------+
| st_centroid_agg |
+-----------------+
| POINT(0 1)      |
+-----------------+

https://en.wikipedia.org/wiki/Geohash "GeoHash"

安全性函数

BigQuery 支持以下安全性函数。

SESSION_USER

SESSION_USER()

说明

返回运行查询的用户的电子邮件地址。

返回数据类型

STRING

示例

SELECT SESSION_USER() as user;

+----------------------+
| user                 |
+----------------------+
| jdoe@example.com     |
+----------------------+

UUID 函数

BigQuery 支持以下通用唯一标识符 (UUID) 函数。

GENERATE_UUID

GENERATE_UUID()

说明

STRING 形式返回随机通用唯一标识符 (UUID)。返回的 STRING 包含 32 个十六进制数字,这些数字由连字符分为五组,具体形式为 8-4-4-4-12。十六进制数字表示符合 RFC 4122 第 4.4 节的 122 个随机位和 6 个固定位。返回的 STRING 是小写字母。

返回数据类型

STRING

示例

以下查询会生成一个随机 UUID。

SELECT GENERATE_UUID() AS uuid;

上述查询会生成如下所示的结果:

+--------------------------------------+
| uuid                                 |
+--------------------------------------+
| 4192bff0-e1e0-43ce-a4db-912808c32493 |
+--------------------------------------+

网络函数

NET.IP_FROM_STRING

NET.IP_FROM_STRING(addr_str)

说明

将 IPv4 或 IPv6 地址从文本 (STRING) 格式转换为网络字节顺序的二进制 (BYTES) 格式。

此函数支持以下 addr_str 格式:

  • IPv4:点分四组格式。例如 10.1.2.3
  • IPv6:冒号分隔格式。例如 1234:5678:90ab:cdef:1234:5678:90ab:cdef。如需查看更多示例,请参阅 IP 版本 6 寻址架构

此函数不支持 CIDR 表示法,例如 10.1.2.3/32

如果此函数收到一个 NULL 输入,则会返回 NULL。如果输入视为无效,则发生 OUT_OF_RANGE 错误。

返回数据类型

BYTES

示例

SELECT
  addr_str, FORMAT("%T", NET.IP_FROM_STRING(addr_str)) AS ip_from_string
FROM UNNEST([
  '48.49.50.51',
  '::1',
  '3031:3233:3435:3637:3839:4041:4243:4445',
  '::ffff:192.0.2.128'
]) AS addr_str;
addr_str ip_from_string
48.49.50.51 b"0123"
::1 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
3031:3233:3435:3637:3839:4041:4243:4445 b"0123456789@ABCDE"
::ffff:192.0.2.128 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x00\x02\x80"

NET.SAFE_IP_FROM_STRING

NET.SAFE_IP_FROM_STRING(addr_str)

说明

类似于 NET.IP_FROM_STRING,但在输入无效的情况下会返回 NULL,而不是抛出错误。

返回数据类型

BYTES

示例

SELECT
  addr_str,
  FORMAT("%T", NET.SAFE_IP_FROM_STRING(addr_str)) AS safe_ip_from_string
FROM UNNEST([
  '48.49.50.51',
  '::1',
  '3031:3233:3435:3637:3839:4041:4243:4445',
  '::ffff:192.0.2.128',
  '48.49.50.51/32',
  '48.49.50',
  '::wxyz'
]) AS addr_str;
addr_str safe_ip_from_string
48.49.50.51 b"0123"
::1 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
3031:3233:3435:3637:3839:4041:4243:4445 b"0123456789@ABCDE"
::ffff:192.0.2.128 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x00\x02\x80"
48.49.50.51/32 NULL
48.49.50 NULL
::wxyz NULL

NET.IP_TO_STRING

NET.IP_TO_STRING(addr_bin)

说明 将 IPv4 或 IPv6 地址从文本 (STRING) 格式转换为网络字节顺序的二进制 (BYTES) 格式。

如果输入为 4 个字节,则此函数返回 STRING 形式的 IPv4 地址。如果输入为 16 个字节,则返回 STRING 形式的 IPv6 地址。

如果此函数收到一个 NULL 输入,则会返回 NULL。如果输入的长度并非 4 或 16,则发生 OUT_OF_RANGE 错误。

返回数据类型

STRING

示例

SELECT FORMAT("%T", x) AS addr_bin, NET.IP_TO_STRING(x) AS ip_to_string
FROM UNNEST([
  b"0123",
  b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
  b"0123456789@ABCDE",
  b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x00\x02\x80"
]) AS x;
addr_bin ip_to_string
b"0123" 48.49.50.51
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" ::1
b"0123456789@ABCDE" 3031:3233:3435:3637:3839:4041:4243:4445
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x00\x02\x80" ::ffff:192.0.2.128

NET.IP_NET_MASK

NET.IP_NET_MASK(num_output_bytes, prefix_length)

说明

返回一个网路掩码:长度等于 num_output_bytes 的一个字节序列,其中第一个 prefix_length 位设置为 1,其他位设置为 0。num_output_bytesprefix_length 为 INT64 类型。如果 num_output_bytes 不是 4(对于 IPv4)或 16(对于 IPv6),则此函数会引发错误。如果 prefix_length 为负或者大于 8 * num_output_bytes,此函数也会引发错误。

返回数据类型

BYTES

示例

SELECT x, y, FORMAT("%T", NET.IP_NET_MASK(x, y)) AS ip_net_mask
FROM UNNEST([
  STRUCT(4 as x, 0 as y),
  (4, 20),
  (4, 32),
  (16, 0),
  (16, 1),
  (16, 128)
]);
x y ip_net_mask
4 0 b"\x00\x00\x00\x00"
4 20 b"\xff\xff\xf0\x00"
4 32 b"\xff\xff\xff\xff"
16 0 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
16 1 b"\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
16 128 b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"

NET.IP_TRUNC

NET.IP_TRUNC(addr_bin, prefix_length)

说明 接受 addr_bin(以网络字节顺序排列的二进制 (BYTES) 格式的 IPv4 或 IPv6 地址),并以相同格式返回子网地址。结果具有与 addr_bin 相同的长度,其中第一个 prefix_length 位等于 addr_bin 中的位,其余位是 0。

如果 LENGTH(addr_bin) 不是 4 或 16,或者 prefix_len 为负或者大于 LENGTH(addr_bin) * 8,此函数会引发错误。

返回数据类型

BYTES

示例

SELECT
  FORMAT("%T", x) as addr_bin, prefix_length,
  FORMAT("%T", NET.IP_TRUNC(x, prefix_length)) AS ip_trunc
FROM UNNEST([
  STRUCT(b"\xAA\xBB\xCC\xDD" as x, 0 as prefix_length),
  (b"\xAA\xBB\xCC\xDD", 11), (b"\xAA\xBB\xCC\xDD", 12),
  (b"\xAA\xBB\xCC\xDD", 24), (b"\xAA\xBB\xCC\xDD", 32),
  (b'0123456789@ABCDE', 80)
]);
addr_bin prefix_length ip_trunc
b"\xaa\xbb\xcc\xdd" 0 b"\x00\x00\x00\x00"
b"\xaa\xbb\xcc\xdd" 11 b"\xaa\xa0\x00\x00"
b"\xaa\xbb\xcc\xdd" 12 b"\xaa\xb0\x00\x00"
b"\xaa\xbb\xcc\xdd" 24 b"\xaa\xbb\xcc\x00"
b"\xaa\xbb\xcc\xdd" 32 b"\xaa\xbb\xcc\xdd"
b"0123456789@ABCDE" 80 b"0123456789\x00\x00\x00\x00\x00\x00"

NET.IPV4_FROM_INT64

NET.IPV4_FROM_INT64(integer_value)

说明

将 IPv4 地址从整数格式转换为网络字节顺序的二进制 (BYTES) 格式。在整数输入中,无论主机或客户端采用何种架构,IP 地址的最低有效位都存储为整数最低有效位。例如,1 表示 0.0.0.10x1FF 表示 0.0.1.255

此函数会检查是否所有最高有效 32 位均为 0,或者是否所有最高有效 33 位均为 1(从 32 位整数进行有符号扩展)。换句话说,输入应该在 [-0x80000000, 0xFFFFFFFF] 范围内;否则,此函数会引发错误。

此函数不支持 IPv6。

返回数据类型

BYTES

示例

SELECT x, x_hex, FORMAT("%T", NET.IPV4_FROM_INT64(x)) AS ipv4_from_int64
FROM (
  SELECT CAST(x_hex AS INT64) x, x_hex
  FROM UNNEST(["0x0", "0xABCDEF", "0xFFFFFFFF", "-0x1", "-0x2"]) AS x_hex
);
x x_hex ipv4_from_int64
0 0x0 b"\x00\x00\x00\x00"
11259375 0xABCDEF b"\x00\xab\xcd\xef"
4294967295 0xFFFFFFFF b"\xff\xff\xff\xff"
-1 -0x1 b"\xff\xff\xff\xff"
-2 -0x2 b"\xff\xff\xff\xfe"

NET.IPV4_TO_INT64

NET.IPV4_TO_INT64(addr_bin)

说明

将 IPv4 地址从网络字节顺序的二进制 (BYTES) 格式转换为整数格式。在整数输出中,无论主机或客户端采用何种架构,IP 地址的最低有效位都存储为整数最低有效位。例如,1 表示 0.0.0.10x1FF 表示 0.0.1.255。输出范围为 [0, 0xFFFFFFFF]

如果输入长度不是 4,则此函数会引发错误。

此函数不支持 IPv6。

返回数据类型

INT64

示例

SELECT
  FORMAT("%T", x) AS addr_bin,
  FORMAT("0x%X", NET.IPV4_TO_INT64(x)) AS ipv4_to_int64
FROM
UNNEST([b"\x00\x00\x00\x00", b"\x00\xab\xcd\xef", b"\xff\xff\xff\xff"]) AS x;
addr_bin ipv4_to_int64
b"\x00\x00\x00\x00" 0x0
b"\x00\xab\xcd\xef" 0xABCDEF
b"\xff\xff\xff\xff" 0xFFFFFFFF

NET.HOST

NET.HOST(url)

说明

获取一个 STRING 格式的网址,并返回 STRING 格式的主机。为获得最佳结果,网址值应符合 RFC 3986 定义的格式。如果网址值不符合 RFC 3986 格式,此函数会尽最大努力解析输入并返回相关结果。如果函数无法解析输入,则返回 NULL。

注意:此函数不执行任何标准化。

返回数据类型

STRING

示例

SELECT
  FORMAT("%T", input) AS input,
  description,
  FORMAT("%T", NET.HOST(input)) AS host,
  FORMAT("%T", NET.PUBLIC_SUFFIX(input)) AS suffix,
  FORMAT("%T", NET.REG_DOMAIN(input)) AS domain
FROM (
  SELECT "" AS input, "invalid input" AS description
  UNION ALL SELECT "http://abc.xyz", "standard URL"
  UNION ALL SELECT "//user:password@a.b:80/path?query",
                   "standard URL with relative scheme, port, path and query, but no public suffix"
  UNION ALL SELECT "https://[::1]:80", "standard URL with IPv6 host"
  UNION ALL SELECT "http://例子.卷筒纸.中国", "standard URL with internationalized domain name"
  UNION ALL SELECT "    www.Example.Co.UK    ",
                   "non-standard URL with spaces, upper case letters, and without scheme"
  UNION ALL SELECT "mailto:?to=&subject=&body=", "URI rather than URL--unsupported"
);
输入 说明 主机 后缀 域名
"" 输入无效 NULL NULL NULL
"http://abc.xyz" 标准网址 "abc.xyz" "xyz" "abc.xyz"
"//user:password@a.b:80/path?query" 具有相对架构、端口、路径和查询的标准网址,但没有公开后缀 "a.b" NULL NULL
"https://[::1]:80" 采用 IPv6 主机的标准网址 "[::1]" NULL NULL
"http://例子.卷筒纸.中国" 采用国际化域名的标准网址 "例子.卷筒纸.中国" "中国" "卷筒纸.中国"
"    www.Example.Co.UK    " 带有空格、大写字母但没有架构的非标准网址 "www.Example.Co.UK" "Co.UK" "Example.Co.UK"
"mailto:?to=&subject=&body=" URI 而非网址 - 不支持 "mailto" NULL NULL

NET.PUBLIC_SUFFIX

NET.PUBLIC_SUFFIX(url)

说明

接受一个 STRING 格式的网址,并返回 STRING 格式的公共后缀(例如 comorgnet)。公共后缀是在 publicsuffix.org 注册的一个 ICANN 域名。为获得最佳结果,网址值应符合 RFC 3986 定义的格式。如果网址值不符合 RFC 3986 格式,此函数会尽最大努力解析输入并返回相关结果。

如果下述任一条件为 true,则此函数返回 NULL:

  • 它无法通过输入解析主机;
  • 解析得出的主机中间包含相邻点(而非前导或尾随位置);
  • 解析得到的主机不包含任何公开后缀。

在查找公开后缀之前,此函数会临时标准化主机,方法是将大写英文字母转换为小写字母,并使用 Punycode 编码所有非 ASCII 字符。随后,此函数将公开后缀作为原始主机(而非标准化主机)的一部分返回。

注意:此函数不执行 Unicode 标准化

注意publicsuffix.org 的公共后缀数据还包含不公开域名。此函数会忽略不公开域名。

注意:公开后缀数据可能会随着时间的推移而变化。因此,现在生成 NULL 结果的输入可能会在将来生成非 NULL 值。

返回数据类型

STRING

示例

SELECT
  FORMAT("%T", input) AS input,
  description,
  FORMAT("%T", NET.HOST(input)) AS host,
  FORMAT("%T", NET.PUBLIC_SUFFIX(input)) AS suffix,
  FORMAT("%T", NET.REG_DOMAIN(input)) AS domain
FROM (
  SELECT "" AS input, "invalid input" AS description
  UNION ALL SELECT "http://abc.xyz", "standard URL"
  UNION ALL SELECT "//user:password@a.b:80/path?query",
                   "standard URL with relative scheme, port, path and query, but no public suffix"
  UNION ALL SELECT "https://[::1]:80", "standard URL with IPv6 host"
  UNION ALL SELECT "http://例子.卷筒纸.中国", "standard URL with internationalized domain name"
  UNION ALL SELECT "    www.Example.Co.UK    ",
                   "non-standard URL with spaces, upper case letters, and without scheme"
  UNION ALL SELECT "mailto:?to=&subject=&body=", "URI rather than URL--unsupported"
);
输入 说明 主机 后缀 域名
"" 输入无效 NULL NULL NULL
"http://abc.xyz" 标准网址 "abc.xyz" "xyz" "abc.xyz"
"//user:password@a.b:80/path?query" 具有相对架构、端口、路径和查询的标准网址,但没有公开后缀 "a.b" NULL NULL
"https://[::1]:80" 采用 IPv6 主机的标准网址 "[::1]" NULL NULL
"http://例子.卷筒纸.中国" 采用国际化域名的标准网址 "例子.卷筒纸.中国" "中国" "卷筒纸.中国"
"    www.Example.Co.UK    " 带有空格、大写字母但没有架构的非标准网址 "www.Example.Co.UK" "Co.UK" "Example.Co.UK
"mailto:?to=&subject=&body=" URI 而非网址 - 不支持 "mailto" NULL NULL

NET.REG_DOMAIN

NET.REG_DOMAIN(url)

说明

接受一个 STRING 格式的网址,并返回 STRING 格式的已注册或可注册域名(公共后缀加一个前置标签)。为获得最佳结果,网址值应符合 RFC 3986 定义的格式。如果网址值不符合 RFC 3986 格式,此函数会尽最大努力解析输入并返回相关结果。

如果下述任一条件为 true,则此函数返回 NULL:

  • 它无法通过输入解析主机;
  • 解析得出的主机中间包含相邻点(而非前导或尾随位置);
  • 解析得到的主机不包含任何公开后缀;
  • 解析得出的主机只包含公开后缀,而无任何前置标签。

在查找公开后缀之前,此函数会临时标准化主机,方法是将大写英文字母转换为小写字母,并使用 Punycode 编码所有非 ASCII 字符。随后,此函数将已注册或可注册域名作为原始主机(而非标准化主机)的一部分返回。

注意:此函数不执行 Unicode 标准化

注意publicsuffix.org 的公共后缀数据还包含不公开域名。此函数不会将不公开域名视为公开后缀。例如,如果“us.com”是公开后缀数据中的一个不公开域名,NET.REG_DOMAIN("foo.us.com") 会返回“us.com”(公开后缀“com”加上前置标签“us”)而非“foo.us.com”(不公开域名“us.com”加上前置标签“foo”)。

注意:公开后缀数据可能会随着时间的推移而变化。因此,现在生成 NULL 结果的输入可能会在将来生成非 NULL 值。

返回数据类型

STRING

示例

SELECT
  FORMAT("%T", input) AS input,
  description,
  FORMAT("%T", NET.HOST(input)) AS host,
  FORMAT("%T", NET.PUBLIC_SUFFIX(input)) AS suffix,
  FORMAT("%T", NET.REG_DOMAIN(input)) AS domain
FROM (
  SELECT "" AS input, "invalid input" AS description
  UNION ALL SELECT "http://abc.xyz", "standard URL"
  UNION ALL SELECT "//user:password@a.b:80/path?query",
                   "standard URL with relative scheme, port, path and query, but no public suffix"
  UNION ALL SELECT "https://[::1]:80", "standard URL with IPv6 host"
  UNION ALL SELECT "http://例子.卷筒纸.中国", "standard URL with internationalized domain name"
  UNION ALL SELECT "    www.Example.Co.UK    ",
                   "non-standard URL with spaces, upper case letters, and without scheme"
  UNION ALL SELECT "mailto:?to=&subject=&body=", "URI rather than URL--unsupported"
);
输入 说明 主机 后缀 域名
"" 输入无效 NULL NULL NULL
"http://abc.xyz" 标准网址 "abc.xyz" "xyz" "abc.xyz"
"//user:password@a.b:80/path?query" 具有相对架构、端口、路径和查询的标准网址,但没有公开后缀 "a.b" NULL NULL
"https://[::1]:80" 采用 IPv6 主机的标准网址 "[::1]" NULL NULL
"http://例子.卷筒纸.中国" 采用国际化域名的标准网址 "例子.卷筒纸.中国" "中国" "卷筒纸.中国"
"    www.Example.Co.UK    " 带有空格、大写字母但没有架构的非标准网址 "www.Example.Co.UK" "Co.UK" "Example.Co.UK"
"mailto:?to=&subject=&body=" URI 而非网址 - 不支持 "mailto" NULL NULL

运算符

运算符由特殊字符或关键字表示;它们不使用函数调用语法。一个运算符可操作任意数量的数据输入(也称为操作数),并返回结果。

常见约定:

  • 除非另有说明,否则当一个操作数为 NULL 时,所有运算符均返回 NULL
  • 如果计算结果溢出,所有运算符都将引发错误。
  • 对于所有浮点运算,如果一个操作数是 +/-infNaN,则可能仅返回 +/-infNaN。在其他情况下,返回一个错误。

下表按从高到低的优先顺序(即在语句中计算的顺序)列出所有 BigQuery 运算符。

优先顺序 运算符 输入数据类型 名称 运算符元数
1 . STRUCT
成员字段访问运算符 二元
  [ ] ARRAY 数组位置。必须与 OFFSET 或 ORDINAL 一起使用 - 详见 ARRAY 函数 二元
2 - 所有数字类型 一元取反 一元
  ~ 整数或 BYTES 按位非 一元
3 * 所有数字类型 二元
  / 所有数字类型 二元
4 + 所有数字类型 二元
  - 所有数字类型 二元
5 << 整数或 BYTES 按位左移 二元
  >> 整数或 BYTES 按位右移 二元
6 & 整数或 BYTES 按位与 二元
7 ^ 整数或 BYTES 按位异或 二元
8 | 整数或 BYTES 按位或 二元
9(比较运算符) = 任何可以进行比较的类型。完整列表请参阅数据类型 等于 二元
  < 任何可以进行比较的类型。完整列表请参阅数据类型 小于 二元
  > 任何可以进行比较的类型。完整列表请参阅数据类型 大于 二元
  <= 任何可以进行比较的类型。完整列表请参阅数据类型 小于或等于 二元
  >= 任何可以进行比较的类型。完整列表请参阅数据类型 大于或等于 二元
  !=、<> 任何可以进行比较的类型。完整列表请参阅数据类型 不等于 二元
  [NOT] LIKE STRING 和字节 值与指定的模式[不]匹配 二元
  [NOT] BETWEEN 任何可以进行比较的类型。请参阅数据类型以获取相关列表。 值[不]在指定的范围内 二元
  [NOT] IN 任何可以进行比较的类型。请参阅数据类型以获取相关列表。 值[不]属于指定的值集 二元
  IS [NOT] NULL 全部 值[不]是 NULL 一元
  IS [NOT] TRUE BOOL 值[不]为 TRUE。 一元
  IS [NOT] FALSE BOOL 值[不]为 FALSE。 一元
10 NOT BOOL 逻辑非 一元
11 AND BOOL 逻辑与 二元
12 OR BOOL 逻辑或 二元

优先级相同的运算符采用左结合方式。这表示这些运算符从左开始向右组合在一起。例如,在如下表达式中:

x AND y AND z

正确的解释方式如下

( ( x AND y ) AND z )

在如下表达式中:

x * y / z

正确的解释方法如下:

( ( x * y ) / z )

所有比较运算符的优先级相同,但比较运算符不具有结合性。因此,需要使用括号来避免歧义。例如:

(x < y) IS FALSE

元素访问运算符

运算符 语法 输入数据类型 结果数据类型 说明
. expression.fieldname1... STRUCT
fieldname1 中存储的类型 T 点运算符。可用于访问嵌套字段,例如 expression.fieldname1.fieldname2...
[ ] array_expression [position_keyword (int_expression ) ] 参见 ARRAY 函数。 ARRAY 中存储的类型 T position_keyword 是 OFFSET 或 ORDINAL。如需了解使用此运算符的两个函数,请参阅 ARRAY 函数

算术运算符

除非以下说明中另行指出,否则所有算术运算符都接受数字类型 T 的输入且结果类型为类型 T:

名称 语法
X + Y
X - Y
X * Y
X / Y
一元取反 - X

注意:除以 0 的运算会返回一个错误。要返回不同的结果,请考虑使用 IEEE_DIVIDE 或 SAFE_DIVIDE 函数。

加法和乘法的结果类型:

 INT64NUMERICFLOAT64
INT64INT64NUMERICFLOAT64
NUMERICNUMERICNUMERICFLOAT64
FLOAT64FLOAT64FLOAT64FLOAT64

减法的结果类型:

 INT64NUMERICFLOAT64
INT64INT64NUMERICFLOAT64
NUMERICNUMERICNUMERICFLOAT64
FLOAT64FLOAT64FLOAT64FLOAT64

除法的结果类型:

 INT64NUMERICFLOAT64
INT64FLOAT64NUMERICFLOAT64
NUMERICNUMERICNUMERICFLOAT64
FLOAT64FLOAT64FLOAT64FLOAT64

一元取反的结果类型:

输入数据类型 结果数据类型
INT64 INT64
NUMERIC NUMERIC
FLOAT64 FLOAT64

按位运算符

所有按位运算符均返回与第一个操作符相同的类型。

名称 语法 输入数据类型 说明
按位非 ~ X 整数或 BYTES 对每一位进行逻辑非运算,生成给定二进制值的补码。
按位或 X | Y X:整数或 BYTES
Y:类型与 X 相同
采用长度相等的两位模式,并对每一对相应位执行逻辑可兼或运算。如果 Y 为负,则此运算符引发一个错误。
按位异或 X ^ Y X:整数或 BYTES
Y:类型与 X 相同
采用长度相等的两位模式,并对每一对相应位执行逻辑排斥或运算。如果 Y 为负,则此运算符引发一个错误。
按位与 X & Y X:整数或 BYTES
Y:类型与 X 相同
采用长度相等的两位模式,并在每一对相应位上执行逻辑与运算。如果 Y 为负,则此运算符引发一个错误。
左移 X << Y X:整数或 BYTES
Y:INT64
将第一个操作数 X 左移。如果第二个操作数 Y 大于或等于第一个操作数 X 的位长度(例如,如果 X 的类型是 INT64,则其位长度是 64),则此运算符返回 0,或者返回 b'\x00' 字节序列。如果 Y 为负,则此运算符引发一个错误。
右移 X >> Y X:整数或 BYTES
Y:INT64
将第一个操作数 X 右移。此运算符不会为位扩展加上符号(即它在左侧的空位上填充 0)。如果第二个操作数 Y 大于或等于第一个操作数 X 的位长度(例如,如果 X 的类型是 INT64,则其位长度是 64),则此运算符返回 0,或者返回 b'\x00' 字节序列。如果 Y 为负,则此运算符引发一个错误。

逻辑运算符

所有逻辑运算符都仅允许 BOOL 输入。

名称 语法 说明
逻辑非 NOT X 如果输入为 TRUE,则返回 FALSE。如果输入为 FALSE,则返回 TRUE。否则返回 NULL
逻辑与 X AND Y 如果至少一个输入为 FALSE,则返回 FALSE。如果 X 和 Y 均为 TRUE,则返回 TRUE。否则返回 NULL
逻辑或 X OR Y 如果 X 和 Y 均为 FALSE,则返回 FALSE。如果至少一个输入为 TRUE,则返回 TRUE。否则返回 NULL

比较运算符

比较运算符始终返回 BOOL。通常,两个操作数的类型必须相同才能进行比较;如果操作数的类型不同,并且 BigQuery 可以在没有精度损失的情况下将这些类型的值转换为某种通用类型,那么 BigQuery 通常会将这些类型强制转换为该通用类型以进行比较;BigQuery 通常会将字面量强制转换为非字面量类型(如果存在)。如需了解可进行比较的数据类型,请参阅数据类型

STRUCT 仅支持 4 种比较运算符:等于 (=)、不等于 (!= 和 <>)以及 IN。

比较这些数据类型时需遵循以下规则:

  • FLOAT64:所有与 NaN 进行的比较都会返回 FALSE(!=<> 除外,它们返回的是 TRUE)。
  • BOOL:FALSE 小于 TRUE。
  • STRING:字符串按代码点逐一进行比较,这意味着如果先对字符串进行标准化,则只有根据规范相等的字符串才能在比较中相等。
  • NULL:根据约定的规定,带 NULL 输入的任何运算均返回 NULL
名称 语法 说明
小于 X < Y 如果 X 小于 Y,则返回 TRUE。
小于或等于 X <= Y 如果 X 小于或等于 Y,则返回 TRUE。
大于 X > Y 如果 X 大于 Y,则返回 TRUE。
大于或等于 X >= Y 如果 X 大于或等于 Y,则返回 TRUE。
等于 X = Y 如果 X 等于 Y,则返回 TRUE。
不等于 X != Y
X <> Y
如果 X 不等于 Y,则返回 TRUE。
BETWEEN X [NOT] BETWEEN Y AND Z 如果 X [不]在指定的范围内,则返回 TRUE。“X BETWEEN Y AND Z”的结果等于“Y <= X AND X <= Z”,但 X 在第一项运算中只计算一次。
LIKE X [NOT] LIKE Y 检查第一个操作数 X 中的 STRING 是否与第二个操作数 Y 指定的模式相匹配。表达式可包含以下字符:
  • 百分号“%”匹配任意数量的字符或字节
  • 下划线“_”与单个字符或字节相匹配
  • 可以使用两个反斜杠转义“\”、“_”或“%”。例如, "\\%"。如果使用原始字符串,则只需要一个反斜杠。例如,r"\%".
IN 多个 - 见下文 如果右侧操作数为空,则返回 FALSE。如果左侧操作数为 NULL,则返回 NULL。如果右侧操作数包含 NULL,则返回 TRUE 或 NULL(始终不会返回 FALSE)。IN 任一侧的参数为常规表达式。虽然操作数都无需为字面量,但通常在右侧使用字面量。X 只计算一次。

在测试具有等式的 STRUCT 数据类型的值时,可能出现一个或多个字段为 NULL 的情况。在此类情况下:

  • 如果所有非 NULL 字符值均相等,则比较返回 NULL。
  • 如果任一 NULL 字段值不相等,则比较返回 false。

下表显示了在 STRUCT 数据类型具有带 NULL 值的字段时如何进行比较。

Struct1 Struct2 Struct1 = Struct2
STRUCT(1, NULL) STRUCT(1, NULL) NULL
STRUCT(1, NULL) STRUCT(2, NULL) FALSE
STRUCT(1,2) STRUCT(1, NULL)

NULL

IN 运算符

IN 运算符支持以下语法:

x [NOT] IN (y, z, ... ) # Requires at least one element
x [NOT] IN (<subquery>)
x [NOT] IN UNNEST(<array expression>) # analysis error if the expression
                                      # does not return an ARRAY type.

IN 运算符任一侧的参数是常规表达式。右侧表达式通常使用字面量;但这并非必要条件。

以下表达式的语义:

x IN (y, z, ...)

被定义为等效于:

(x = y) OR (x = z) OR ...

并且子查询和数组形式具有相似定义。

x NOT IN ...

等效于:

NOT(x IN ...)

UNNEST 形式将数组扫描视为 FROM 子句中的 UNNEST

x [NOT] IN UNNEST(<array expression>)

该形式通常与 ARRAY 参数一起使用。例如:

x IN UNNEST(@array_parameter)

注意NULL 值的 ARRAY 被视为等效于空 ARRAY。

如需详细了解如何使用此语法,请参阅数组主题。

使用 IN 运算符时,需遵循以下语义:

  • 右侧表达式为空的 IN 始终为 FALSE
  • 左侧表达式为 NULL 且右侧表达式非空的 IN 始终为 NULL
  • IN 列表中具有 NULLIN 仅可返回 TRUE 或 NULL,始终不会返回 FALSE
  • NULL IN (NULL) 返回 NULL
  • IN UNNEST(<NULL array>) 返回 FALSE(而不是 NULL
  • IN 列表中具有 NULLNOT IN 只能返回 FALSE 或 NULL,永远不会返回 TRUE

IN 可通过 struct 构造函数语法与多个部分组成的键一起使用。例如:

(Key1, Key2) IN ( (12,34), (56,78) )
(Key1, Key2) IN ( SELECT (table.a, table.b) FROM table )

如需详细了解此语法,请参阅“数据类型”主题的 Struct 类型部分。

IS 运算符

IS 运算符针对其正在测试的条件返回 TRUE 或 FALSE。与数学函数定义的 IS_INF 和 IS_NAN 函数不同,它们永远不会返回 NULL(即使是对于 NULL 输入也是如此)。如果存在 NOT,则取输出 BOOL 值的反值。

函数语法 输入数据类型 结果数据类型 说明

X IS [NOT] NULL
任何值类型 BOOL 如果操作数 X 计算结果为 NULL,则返回 TRUE;否则返回 FALSE。

X IS [NOT] TRUE
BOOL BOOL 如果 BOOL 操作数计算结果为 TRUE,则返回 TRUE;否则返回 FALSE。

X IS [NOT] FALSE
BOOL BOOL 如果 BOOL 操作数计算结果为 FALSE,则返回 TRUE;否则返回 FALSE。

条件表达式

条件表达式对其输入的计算顺序施加约束。实质上,它们按从左到右的顺序进行计算,具有短路机制,并且只计算所选的输出值。与此相反,在调用函数之前,对常规函数的所有输入都要进行计算。条件表达式中的短路机制可用于处理错误或调整性能。

语法 输入数据类型 结果数据类型 说明

CASE expr
  WHEN value THEN result
  [WHEN ...]
  [ELSE else_result]
  END
exprvalue:任何类型 resultelse_result:输入类型的超类型。 expr 与每个连续的 WHEN 子句进行比较,并在该比较返回 true 的情况下返回第一个结果。剩余的 WHEN 子句和 else_result 不进行计算。如果 expr = value 比较针对所有 WHEN 子句都返回 false 或 NULL,则返回 else_result(如果有);如果没有,则返回 NULLexprvalue 表达式必须可隐式强制转换为常用超类型;针对强制转换后的值执行等式比较。resultelse_result 表达式必须可强制转换为常用超类型。

CASE
  WHEN cond1 THEN result
  [WHEN cond2...]
  [ELSE else_result]
  END
cond:BOOL resultelse_result:输入类型的超类型。 计算每个连续 WHEN 子句的条件 cond,并在条件为 true 的情况下返回第一个结果;其余所有 WHEN 子句和 else_result 均不进行计算。如果所有条件均为 false 或 NULL,则返回 else_result(如果有);如果没有,则返回 NULLresultelse_result 表达式必须可隐式强制转换为常用超类型。
COALESCE(expr1, ..., exprN) 任何类型 输入类型的超类型 返回第一个非 NULL 表达式的值。其余表达式不进行计算。所有输入表达式必须均可隐式强制转换为常用超类型。
IF(cond, true_result, else_result) cond:BOOL true_resultelse_result:任何类型。 如果 cond 为 true,则返回 true_result,否则返回 else_result。如果 cond 为 true,则不计算 else_result。如果 cond 为 false 或 NULL,则 true_result 不进行计算。true_resultelse_result 必须强制转换为常用超类型。
IFNULL(expr, null_result) 任何类型 输入类型的任何类型或超类型。 如果 exprNULL,则返回 null_result。否则,返回 expr。如果 expr 不是 NULL,则 null_result 不进行计算。exprnull_result 必须可隐式强制转换为常用超类型。相当于 COALESCE(expr, null_result)
NULLIF(expression, expression_to_match) T 的任何 T 类型或子类型 T 的任何 T 类型或子类型 如果 NULL 为 true,则返回 expression = expression_to_match;否则返回 expressionexpressionexpression_to_match 必须均可隐式强制转换为常用超类型;针对强制转换后的值执行等式比较。

表达式子查询

存在 4 种类型的表达式子查询(即用作表达式的子查询)。与列或表格相反,表达式子查询返回 NULL 或单个值,且必须用括号括起来。如需更全面的子查询讨论信息,请参阅子查询

子查询类型 结果数据类型 说明
标量 任何 T 类型 表达式中用括号括起的子查询(例如在 SELECT 列表或 WHERE 子句中)被解释为标量子查询。标量子查询中的 SELECT 列表只能有一个字段。如果子查询只返回一行,则该单一值就是标量子查询的结果。如果子查询未返回任何行,则标量子查询的值为 NULL。如果子查询采用 SELECT AS STRUCT 格式编写,则它可包含多个列,且返回的值是构造的 STRUCT。在未使用 SELECT AS 的情况下选择多个列会出错。
ARRAY ARRAY 可使用 SELECT AS STRUCT 构建 struct 数组;相反,在未使用 SELECT AS 的情况下选择多个列则会出错。如果子查询未返回任何行,则会返回一个空的 ARRAY。永远不会返回 NULL ARRAY。
IN BOOL 出现在 IN 运算符后接的表达式中。子查询必须生成单个列,其类型与等式兼容且表达式位于 IN 运算符的左侧。如果子查询未返回任何行,则返回 FALSE。 x IN () 相当于 x IN (value, value, ...)。如需了解完整语义,请参阅比较运算符中的 IN 运算符。
EXISTS BOOL 如果子查询生成一行或多行,则返回 TRUE。如果子查询未生成任何行,则返回 FALSE。始终不会返回 NULL。它与其他所有表达式子查询不同,不存在关于列列表的规则。可选用任意数量的列,这不影响查询结果。

示例

下述表达式子查询示例假定 t.int_array 具有 ARRAY<INT64> 类型。

类型 子查询 结果数据类型 备注
标量 (SELECT COUNT(*) FROM t.int_array) INT64  
(SELECT DISTINCT i FROM t.int_array i) INT64,可能出现运行时错误  
(SELECT i FROM t.int_array i WHERE i=5) INT64,可能出现运行时错误  
(SELECT ARRAY_AGG(i) FROM t.int_array i) ARRAY 使用 ARRAY_AGG 聚合函数返回 ARRAY。
(SELECT 'xxx' a) STRING  
(SELECT 'xxx' a, 123 b) 错误 由于存在多个列,因此返回一个错误
(SELECT AS STRUCT 'xxx' a, 123 b) STRUCT  
(SELECT AS STRUCT 'xxx' a) STRUCT  
ARRAY ARRAY(SELECT COUNT(*) FROM t.int_array) 大小为 1 的 ARRAY  
ARRAY(SELECT x FROM t) ARRAY  
ARRAY(SELECT 5 a, COUNT(*) b FROM t.int_array) 错误 由于存在多个列,因此返回一个错误
ARRAY(SELECT AS STRUCT 5 a, COUNT(*) b FROM t.int_array) ARRAY  
ARRAY(SELECT AS STRUCT i FROM t.int_array i) ARRAY 创建由单字段 STRUCT 构成的 ARRAY
ARRAY(SELECT AS STRUCT 1 x, 2, 3 x) ARRAY 返回具有匿名或重复字段的 STRUCT 的 ARRAY。
ARRAY(SELECT AS TypeName SUM(x) a, SUM(y) b, SUM(z) c from t) array<TypeName> 选择一个命名类型。假定 TypeName 是具有字段 a、b 和 c 的 STRUCT 类型。
STRUCT (SELECT AS STRUCT 1 x, 2, 3 x) STRUCT 构造具有匿名或重复字段的 STRUCT。
EXISTS EXISTS(SELECT x,y,z FROM table WHERE y=z) BOOL  
NOT EXISTS(SELECT x,y,z FROM table WHERE y=z) BOOL  
IN x IN (SELECT y FROM table WHERE z) BOOL  
x NOT IN (SELECT y FROM table WHERE z) BOOL  

调试函数

BigQuery 支持以下调试函数。

ERROR

ERROR(error_message)

说明

返回错误。error_message 参数为 STRING

BigQuery 处理 ERROR 的方式与处理可能导致错误的任何表达式相同:没有针对计算顺序的特别保证。

返回数据类型

BigQuery 会根据上下文推断返回类型。

示例

在以下示例中,如果行的值与两个已定义值均不匹配,则查询将返回一条错误消息。

SELECT
  CASE
    WHEN value = 'foo' THEN 'Value is foo.'
    WHEN value = 'bar' THEN 'Value is bar.'
    ELSE ERROR(concat('Found unexpected value: ', value))
  END AS new_value
FROM (
  SELECT 'foo' AS value UNION ALL
  SELECT 'bar' AS value UNION ALL
  SELECT 'baz' AS value);

Found unexpected value: baz

在以下示例中,BigQuery 可能会在 x > 0 条件之前或之后对 ERROR 函数求值,因为 BigQuery 通常不保证对 WHERE 子句条件之间进行排序,对于 ERROR 函数也不提供任何特别保证。

SELECT *
FROM (SELECT -1 AS x)
WHERE x > 0 AND ERROR('Example error');

在下一个示例中,WHERE 子句对 IF 条件求值,这能确保 BigQuery 仅在条件失败时对 ERROR 函数求值。

SELECT *
FROM (SELECT -1 AS x)
WHERE IF(x > 0, true, ERROR(FORMAT('Error: x must be positive but is %t', x)));'

Error: x must be positive but is -1
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面