标准 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. 前缀。

转换规则

“转换”包括但不限于类型转换 (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([NULL, 1, -2, 3, -2, 1, NULL]) AS x;

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

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

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

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([NULL, 1, -2, 3, -2, 1, NULL]) AS x;
+-------------------------------+
| array_agg                     |
+-------------------------------+
| [NULL, NULL, 1, 1, -2, -2, 3] |
+-------------------------------+

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

+----------------------+
| array_agg            |
+----------------------+
| [NULL, 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([NULL, 1, -2, 3, -2, 1, NULL]) AS x;

+------+-------------------------------+
| x    | array_agg                     |
+------+-------------------------------+
| NULL | [NULL, NULL]                  |
| NULL | [NULL, NULL]                  |
| 1    | [NULL, NULL, 1, 1]            |
| 1    | [NULL, NULL, 1, 1]            |
| -2   | [NULL, NULL, 1, 1, -2, -2]    |
| -2   | [NULL, NULL, 1, 1, -2, -2]    |
| 3    | [NULL, NULL, 1, 1, -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

支持的参数类型

任意数据类型(STRUCT 和 ARRAY 除外)

可选子句

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

支持的参数类型

任意数据类型(STRUCT 和 ARRAY 除外)

可选子句

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),但在处理海量输入时性能较为出众。

支持的参数类型

除以下几项以外的所有数据类型:

  • ARRAY
  • STRUCT

返回的数据类型

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 可以是除以下数据类型外的任意受支持的数据类型:

  • ARRAY
  • STRUCT

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(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 值。

返回的数据类型

返回类型为 STRUCT 的 ARRAY 结果。该 STRUCT 包含两个字段。第一个字段包含一个 input 值。第二个字段包含一个 INT64 值,指定返回 input 的次数。

如果不存在任何输入行,则返回 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++ 草图中。每个草图均使用 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 中设置的位数。对于整数,这是 2 的补码形式的位数。

返回数据类型

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 时的错误。

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 的余弦。始终有效。

COSH

COSH(X)

说明

计算 X 的双曲余弦。如果发生溢出,则生成错误。

ACOS

ACOS(X)

说明

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

ACOSH

ACOSH(X)

说明

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

SIN

SIN(X)

说明

计算 X 的正弦。始终有效。

SINH

SINH(X)

说明

计算 X 的双曲正弦。如果发生溢出,则生成错误。

ASIN

ASIN(X)

说明

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

ASINH

ASINH(X)

说明

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

TAN

TAN(X)

说明

计算 X 的正切值。如果发生溢出,则生成错误。

TANH

TANH(X)

说明

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

ATAN

ATAN(X)

说明

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

ATANH

ATANH(X)

说明

计算 X 的反双曲正切。如果 X 的绝对值大于或等于 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+
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() 函数的扩展用斜体表示。

说明符 说明 示例 类型
d 或 i 十进制整数 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 部分 sample
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) 范围以外的字符,则会返回错误。字符不区分大小写。要将 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 $.
SELECT
  email,
  REGEXP_CONTAINS(email, r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
    AS valid_email_address
FROM
  (SELECT
    ["foo@example.com", "bar@example.org", "www.example.net"]
    AS addresses),
  UNNEST(addresses) AS email;

+-----------------+---------------------+
| email           | valid_email_address |
+-----------------+---------------------+
| foo@example.com | true                |
| bar@example.org | true                |
| www.example.net | 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 函数仅替换非重叠的匹配项。例如,替换 ana 结果中的 banana 时仅替换一处,而不是两处。

如果 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)

说明

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

返回类型

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              |
| {"first":"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 函数将返回 STRUCTARRAY 类型。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_datestep 值为正数。

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    |
+---------+

以下命令返回一个日期数组,使用作为 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 值为 MICROSECONDMILLISECONDSECONDMINUTEHOURDAY

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

示例

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 格式年份。
%g 用十进制数 (00-99) 表示的两位数的 ISO 8601 格式年份。
%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

示例

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

示例

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)

说明

使用 format_string 和时间戳的字符串表示形式返回 TIMESTAMP 对象。如需查看此函数支持的格式元素列表,请参阅 DATETIME 支持的格式元素

使用 PARSE_DATETIME 时,请注意以下几点:

  • 未指定的字段。 任何未指定的字段均从 1970-01-01 00:00:00.0 开始初始化。例如,如果未指定年份,则默认为 1970,依此类推。
  • 不区分大小写的名称。 MondayFebruary 等名称不区分大小写。
  • 空格。 格式字符串中的一个或更多连续空格与 DATETIME 字符串中的零个或更多连续空格相匹配。此外,始终可在 DATETIME 字符串中使用前导空格和尾随空格(即使这些空格不在格式字符串中)。
  • 格式优先。 如果两个(或更多)格式元素的信息出现重叠(例如 %F%Y 均对年份有影响),则最后一个元素通常会替换前面的所有元素,但要注意存在一些例外情况(请参阅 %s%C%y 的说明)。

返回数据类型

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 格式年份。
%g 用十进制数 (00-99) 表示的两位数的 ISO 8601 格式年份。
%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

示例

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 格式年份。
%g 用十进制数 (00-99) 表示的两位数的 ISO 8601 格式年份。
%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 支持以下安全性函数。

SESSION_USER

SESSION_USER()

说明

返回运行查询的用户的电子邮件地址。

返回数据类型

STRING

示例

SELECT SESSION_USER() as user;

+----------------------+
| user                 |
+----------------------+
| jdoe@example.com     |
+----------------------+

网络函数

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.Google.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.Google.Co.UK    " 带有空格、大写字母但没有架构的非标准网址 "www.Google.Co.UK" "Co.UK" "Google.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.Google.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.Google.Co.UK    " 带有空格、大写字母但没有架构的非标准网址 "www.Google.Co.UK" "Co.UK" "Google.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.Google.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.Google.Co.UK    " 带有空格、大写字母但没有架构的非标准网址 "www.Google.Co.UK" "Co.UK" "Google.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

优于:

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。
介于 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 形式将数组扫描项视为 UNNEST 子句中的 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 可通过 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
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面