This topic is a compilation of functions, operators, and conditional expressions.
To learn more about how to call functions, function call rules,
the SAFE
prefix, and special types of arguments,
see Function calls.
OPERATORS AND CONDITIONALS
Operators
GoogleSQL for BigQuery supports operators. Operators are represented by special characters or keywords; they do not use function call syntax. An operator manipulates any number of data inputs, also called operands, and returns a result.
Common conventions:
- Unless otherwise specified, all operators return
NULL
when one of the operands isNULL
. - All operators will throw an error if the computation result overflows.
- For all floating point operations,
+/-inf
andNaN
may only be returned if one of the operands is+/-inf
orNaN
. In other cases, an error is returned.
Operator precedence
The following table lists all GoogleSQL operators from highest to lowest precedence, i.e., the order in which they will be evaluated within a statement.
Order of Precedence | Operator | Input Data Types | Name | Operator Arity |
---|---|---|---|---|
1 | Field access operator |
STRUCT JSON |
Field access operator | Binary |
Array subscript operator | ARRAY |
Array position. Must be used with OFFSET or ORDINAL —see
Array Functions
. |
Binary | |
JSON subscript operator | JSON |
Field name or array position in JSON. | Binary | |
2 | + |
All numeric types | Unary plus | Unary |
- |
All numeric types | Unary minus | Unary | |
~ |
Integer or BYTES |
Bitwise not | Unary | |
3 | * |
All numeric types | Multiplication | Binary |
/ |
All numeric types | Division | Binary | |
|| |
STRING , BYTES , or ARRAY<T> |
Concatenation operator | Binary | |
4 | + |
All numeric types, DATE with
INT64
, INTERVAL
|
Addition | Binary |
- |
All numeric types, DATE with
INT64
, INTERVAL
|
Subtraction | Binary | |
5 | << |
Integer or BYTES |
Bitwise left-shift | Binary |
>> |
Integer or BYTES |
Bitwise right-shift | Binary | |
6 | & |
Integer or BYTES |
Bitwise and | Binary |
7 | ^ |
Integer or BYTES |
Bitwise xor | Binary |
8 | | |
Integer or BYTES |
Bitwise or | Binary |
9 (Comparison Operators) | = |
Any comparable type. See Data Types for a complete list. | Equal | Binary |
< |
Any comparable type. See Data Types for a complete list. | Less than | Binary | |
> |
Any comparable type. See Data Types for a complete list. | Greater than | Binary | |
<= |
Any comparable type. See Data Types for a complete list. | Less than or equal to | Binary | |
>= |
Any comparable type. See Data Types for a complete list. | Greater than or equal to | Binary | |
!= , <> |
Any comparable type. See Data Types for a complete list. | Not equal | Binary | |
[NOT] LIKE |
STRING and BYTES |
Value does [not] match the pattern specified | Binary | |
Quantified LIKE | STRING and BYTES |
Checks a search value for matches against several patterns. | Binary | |
[NOT] BETWEEN |
Any comparable types. See Data Types for a complete list. | Value is [not] within the range specified | Binary | |
[NOT] IN |
Any comparable types. See Data Types for a complete list. | Value is [not] in the set of values specified | Binary | |
IS [NOT] NULL |
All | Value is [not] NULL |
Unary | |
IS [NOT] TRUE |
BOOL |
Value is [not] TRUE . |
Unary | |
IS [NOT] FALSE |
BOOL |
Value is [not] FALSE . |
Unary | |
10 | NOT |
BOOL |
Logical NOT |
Unary |
11 | AND |
BOOL |
Logical AND |
Binary |
12 | OR |
BOOL |
Logical OR |
Binary |
Operators with the same precedence are left associative. This means that those operators are grouped together starting from the left and moving right. For example, the expression:
x AND y AND z
is interpreted as
( ( x AND y ) AND z )
The expression:
x * y / z
is interpreted as:
( ( x * y ) / z )
All comparison operators have the same priority, but comparison operators are not associative. Therefore, parentheses are required in order to resolve ambiguity. For example:
(x < y) IS FALSE
Operator list
Name | Summary |
---|---|
Field access operator | Gets the value of a field. |
Array subscript operator | Gets a value from an array at a specific position. |
Struct subscript operator | Gets the value of a field at a selected position in a struct. |
JSON subscript operator | Gets a value of an array element or field in a JSON expression. |
Arithmetic operators | Performs arithmetic operations. |
Date arithmetics operators | Performs arithmetic operations on dates. |
Datetime subtraction | Computes the difference between two datetimes as an interval. |
Interval arithmetic operators | Adds an interval to a datetime or subtracts an interval from a datetime. |
Bitwise operators | Performs bit manipulation. |
Logical operators |
Tests for the truth of some condition and produces TRUE ,
FALSE , or NULL .
|
Comparison operators |
Compares operands and produces the results of the comparison as a
BOOL value.
|
EXISTS operator
|
Checks if a subquery produces one or more rows. |
IN operator
|
Checks for an equal value in a set of values. |
IS operators
|
Checks for the truth of a condition and produces either TRUE or
FALSE .
|
IS DISTINCT FROM operator
|
Checks if values are considered to be distinct from each other. |
LIKE operator
|
Checks if values are like or not like one another. |
Quantified LIKE operator
|
Checks a search value for matches against several patterns. |
Concatenation operator | Combines multiple values into one. |
Field access operator
expression.fieldname[. ...]
Description
Gets the value of a field. Alternatively known as the dot operator. Can be
used to access nested fields. For example, expression.fieldname1.fieldname2
.
Input values:
STRUCT
JSON
Return type
- For
STRUCT
: SQL data type offieldname
. If a field is not found in the struct, an error is thrown. - For
JSON
:JSON
. If a field is not found in a JSON value, a SQLNULL
is returned.
Example
In the following example, the field access operations are .address
and
.country
.
SELECT
STRUCT(
STRUCT('Yonge Street' AS street, 'Canada' AS country)
AS address).address.country
/*---------*
| country |
+---------+
| Canada |
*---------*/
Array subscript operator
array_expression "[" array_subscript_specifier "]"
array_subscript_specifier:
{ index | position_keyword(index) }
position_keyword:
{ OFFSET | SAFE_OFFSET | ORDINAL | SAFE_ORDINAL }
Description
Gets a value from an array at a specific position.
Input values:
array_expression
: The input array.position_keyword(index)
: Determines where the index for the array should start and how out-of-range indexes are handled. The index is an integer that represents a specific position in the array.OFFSET(index)
: The index starts at zero. Produces an error if the index is out of range. To produceNULL
instead of an error, useSAFE_OFFSET(index)
. This position keyword produces the same result asindex
by itself.SAFE_OFFSET(index)
: The index starts at zero. ReturnsNULL
if the index is out of range.ORDINAL(index)
: The index starts at one. Produces an error if the index is out of range. To produceNULL
instead of an error, useSAFE_ORDINAL(index)
.SAFE_ORDINAL(index)
: The index starts at one. ReturnsNULL
if the index is out of range.
index
: An integer that represents a specific position in the array. If used by itself without a position keyword, the index starts at zero and produces an error if the index is out of range. To produceNULL
instead of an error, use theSAFE_OFFSET(index)
orSAFE_ORDINAL(index)
position keyword.
Return type
T
where array_expression
is ARRAY<T>
.
Examples
In following query, the array subscript operator is used to return values at
specific position in item_array
. This query also shows what happens when you
reference an index (6
) in an array that is out of range. If the SAFE
prefix
is included, NULL
is returned, otherwise an error is produced.
SELECT
["coffee", "tea", "milk"] AS item_array,
["coffee", "tea", "milk"][0] AS item_index,
["coffee", "tea", "milk"][OFFSET(0)] AS item_offset,
["coffee", "tea", "milk"][ORDINAL(1)] AS item_ordinal,
["coffee", "tea", "milk"][SAFE_OFFSET(6)] AS item_safe_offset
/*---------------------+------------+-------------+--------------+------------------*
| item_array | item_index | item_offset | item_ordinal | item_safe_offset |
+---------------------+------------+-------------+--------------+------------------+
| [coffee, tea, milk] | coffee | coffee | coffee | NULL |
*----------------------------------+-------------+--------------+------------------*/
When you reference an index that is out of range in an array, and a positional
keyword that begins with SAFE
is not included, an error is produced.
For example:
-- Error. Array index 6 is out of bounds.
SELECT ["coffee", "tea", "milk"][6] AS item_offset
-- Error. Array index 6 is out of bounds.
SELECT ["coffee", "tea", "milk"][OFFSET(6)] AS item_offset
Struct subscript operator
struct_expression "[" struct_subscript_specifier "]"
struct_subscript_specifier:
{ index | position_keyword(index) }
position_keyword:
{ OFFSET | ORDINAL }
Description
Gets the value of a field at a selected position in a struct.
Input types
struct_expression
: The input struct.position_keyword(index)
: Determines where the index for the struct should start and how out-of-range indexes are handled. The index is an integer literal or constant that represents a specific position in the struct.OFFSET(index)
: The index starts at zero. Produces an error if the index is out of range. Produces the same result asindex
by itself.ORDINAL(index)
: The index starts at one. Produces an error if the index is out of range.
index
: An integer literal or constant that represents a specific position in the struct. If used by itself without a position keyword, the index starts at zero and produces an error if the index is out of range.
Examples
In following query, the struct subscript operator is used to return values at
specific locations in item_struct
using position keywords. This query also
shows what happens when you reference an index (6
) in an struct that is out of
range.
SELECT
STRUCT<INT64, STRING, BOOL>(23, "tea", FALSE)[0] AS field_index,
STRUCT<INT64, STRING, BOOL>(23, "tea", FALSE)[OFFSET(0)] AS field_offset,
STRUCT<INT64, STRING, BOOL>(23, "tea", FALSE)[ORDINAL(1)] AS field_ordinal
/*-------------+--------------+---------------*
| field_index | field_offset | field_ordinal |
+-------------+--------------+---------------+
| 23 | 23 | 23 |
*-------------+--------------+---------------*/
When you reference an index that is out of range in a struct, an error is produced. For example:
-- Error: Field ordinal 6 is out of bounds in STRUCT
SELECT STRUCT<INT64, STRING, BOOL>(23, "tea", FALSE)[6] AS field_offset
-- Error: Field ordinal 6 is out of bounds in STRUCT
SELECT STRUCT<INT64, STRING, BOOL>(23, "tea", FALSE)[OFFSET(6)] AS field_offset
JSON subscript operator
json_expression "[" array_element_id "]"
json_expression "[" field_name "]"
Description
Gets a value of an array element or field in a JSON expression. Can be used to access nested data.
Input values:
JSON expression
: TheJSON
expression that contains an array element or field to return.[array_element_id]
: AnINT64
expression that represents a zero-based index in the array. If a negative value is entered, or the value is greater than or equal to the size of the array, or the JSON expression doesn't represent a JSON array, a SQLNULL
is returned.[field_name]
: ASTRING
expression that represents the name of a field in JSON. If the field name is not found, or the JSON expression is not a JSON object, a SQLNULL
is returned.
Return type
JSON
Example
In the following example:
json_value
is a JSON expression..class
is a JSON field access..students
is a JSON field access.[0]
is a JSON subscript expression with an element offset that accesses the zeroth element of an array in the JSON value.['name']
is a JSON subscript expression with a field name that accesses a field.
SELECT json_value.class.students[0]['name'] AS first_student
FROM
UNNEST(
[
JSON '{"class" : {"students" : [{"name" : "Jane"}]}}',
JSON '{"class" : {"students" : []}}',
JSON '{"class" : {"students" : [{"name" : "John"}, {"name": "Jamie"}]}}'])
AS json_value;
/*-----------------*
| first_student |
+-----------------+
| "Jane" |
| NULL |
| "John" |
*-----------------*/
Arithmetic operators
All arithmetic operators accept input of numeric type T
, and the result type
has type T
unless otherwise indicated in the description below:
Name | Syntax |
---|---|
Addition | X + Y |
Subtraction | X - Y |
Multiplication | X * Y |
Division | X / Y |
Unary Plus | + X |
Unary Minus | - X |
NOTE: Divide by zero operations return an error. To return a different result,
consider the IEEE_DIVIDE
or SAFE_DIVIDE
functions.
Result types for Addition, Subtraction and Multiplication:
INPUT | INT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
---|---|---|---|---|
INT64 | INT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
NUMERIC | NUMERIC | NUMERIC | BIGNUMERIC | FLOAT64 |
BIGNUMERIC | BIGNUMERIC | BIGNUMERIC | BIGNUMERIC | FLOAT64 |
FLOAT64 | FLOAT64 | FLOAT64 | FLOAT64 | FLOAT64 |
Result types for Division:
INPUT | INT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
---|---|---|---|---|
INT64 | FLOAT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
NUMERIC | NUMERIC | NUMERIC | BIGNUMERIC | FLOAT64 |
BIGNUMERIC | BIGNUMERIC | BIGNUMERIC | BIGNUMERIC | FLOAT64 |
FLOAT64 | FLOAT64 | FLOAT64 | FLOAT64 | FLOAT64 |
Result types for Unary Plus:
INPUT | INT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
---|---|---|---|---|
OUTPUT | INT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
Result types for Unary Minus:
INPUT | INT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
---|---|---|---|---|
OUTPUT | INT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
Date arithmetics operators
Operators '+' and '-' can be used for arithmetic operations on dates.
date_expression + int64_expression
int64_expression + date_expression
date_expression - int64_expression
Description
Adds or subtracts int64_expression
days to or from date_expression
. This is
equivalent to DATE_ADD
or DATE_SUB
functions, when interval is expressed in
days.
Return Data Type
DATE
Example
SELECT DATE "2020-09-22" + 1 AS day_later, DATE "2020-09-22" - 7 AS week_ago
/*------------+------------*
| day_later | week_ago |
+------------+------------+
| 2020-09-23 | 2020-09-15 |
*------------+------------*/
Datetime subtraction
date_expression - date_expression
timestamp_expression - timestamp_expression
datetime_expression - datetime_expression
Description
Computes the difference between two datetime values as an interval.
Return Data Type
INTERVAL
Example
SELECT
DATE "2021-05-20" - DATE "2020-04-19" AS date_diff,
TIMESTAMP "2021-06-01 12:34:56.789" - TIMESTAMP "2021-05-31 00:00:00" AS time_diff
/*-------------------+------------------------*
| date_diff | time_diff |
+-------------------+------------------------+
| 0-0 396 0:0:0 | 0-0 0 36:34:56.789 |
*-------------------+------------------------*/
Interval arithmetic operators
Addition and subtraction
date_expression + interval_expression = DATETIME
date_expression - interval_expression = DATETIME
timestamp_expression + interval_expression = TIMESTAMP
timestamp_expression - interval_expression = TIMESTAMP
datetime_expression + interval_expression = DATETIME
datetime_expression - interval_expression = DATETIME
Description
Adds an interval to a datetime value or subtracts an interval from a datetime value.
Example
SELECT
DATE "2021-04-20" + INTERVAL 25 HOUR AS date_plus,
TIMESTAMP "2021-05-02 00:01:02.345" - INTERVAL 10 SECOND AS time_minus;
/*-------------------------+--------------------------------*
| date_plus | time_minus |
+-------------------------+--------------------------------+
| 2021-04-21 01:00:00 | 2021-05-02 00:00:52.345+00 |
*-------------------------+--------------------------------*/
Multiplication and division
interval_expression * integer_expression = INTERVAL
interval_expression / integer_expression = INTERVAL
Description
Multiplies or divides an interval value by an integer.
Example
SELECT
INTERVAL '1:2:3' HOUR TO SECOND * 10 AS mul1,
INTERVAL 35 SECOND * 4 AS mul2,
INTERVAL 10 YEAR / 3 AS div1,
INTERVAL 1 MONTH / 12 AS div2
/*----------------+--------------+-------------+--------------*
| mul1 | mul2 | div1 | div2 |
+----------------+--------------+-------------+--------------+
| 0-0 0 10:20:30 | 0-0 0 0:2:20 | 3-4 0 0:0:0 | 0-0 2 12:0:0 |
*----------------+--------------+-------------+--------------*/
Bitwise operators
All bitwise operators return the same type and the same length as the first operand.
Name | Syntax | Input Data Type | Description |
---|---|---|---|
Bitwise not | ~ X |
Integer or BYTES |
Performs logical negation on each bit, forming the ones' complement of the given binary value. |
Bitwise or | X | Y |
X : Integer or BYTES Y : Same type as X
|
Takes two bit patterns of equal length and performs the logical inclusive
OR operation on each pair of the corresponding bits.
This operator throws an error if X and Y are bytes of
different lengths.
|
Bitwise xor | X ^ Y |
X : Integer or BYTES Y : Same type as X
|
Takes two bit patterns of equal length and performs the
logical exclusive OR operation on each pair of the corresponding
bits.
This operator throws an error if X and Y are bytes of
different lengths.
|
Bitwise and | X & Y |
X : Integer or BYTES Y : Same type as X
|
Takes two bit patterns of equal length and performs the
logical AND operation on each pair of the corresponding bits.
This operator throws an error if X and Y are bytes of
different lengths.
|
Left shift | X << Y |
X : Integer or BYTES Y : INT64
|
Shifts the first operand X to the left.
This operator returns
0 or a byte sequence of b'\x00'
if the second operand Y is greater than or equal to
the bit length of the first operand X (for example, 64
if X has the type INT64 ).
This operator throws an error if Y is negative. |
Right shift | X >> Y |
X : Integer or BYTES Y : INT64 |
Shifts the first operand X to the right. This operator does not
do sign bit extension with a signed type (i.e., it fills vacant bits on the left
with 0 ). This operator returns
0 or a byte sequence of
b'\x00'
if the second operand Y is greater than or equal to
the bit length of the first operand X (for example, 64
if X has the type INT64 ).
This operator throws an error if Y is negative. |
Logical operators
GoogleSQL supports the AND
, OR
, and NOT
logical operators.
Logical operators allow only BOOL
or NULL
input
and use three-valued logic
to produce a result. The result can be TRUE
, FALSE
, or NULL
:
x |
y |
x AND y |
x OR y |
---|---|---|---|
TRUE |
TRUE |
TRUE |
TRUE |
TRUE |
FALSE |
FALSE |
TRUE |
TRUE |
NULL |
NULL |
TRUE |
FALSE |
TRUE |
FALSE |
TRUE |
FALSE |
FALSE |
FALSE |
FALSE |
FALSE |
NULL |
FALSE |
NULL |
NULL |
TRUE |
NULL |
TRUE |
NULL |
FALSE |
FALSE |
NULL |
NULL |
NULL |
NULL |
NULL |
x |
NOT x |
---|---|
TRUE |
FALSE |
FALSE |
TRUE |
NULL |
NULL |
Examples
The examples in this section reference a table called entry_table
:
/*-------*
| entry |
+-------+
| a |
| b |
| c |
| NULL |
*-------*/
SELECT 'a' FROM entry_table WHERE entry = 'a'
-- a => 'a' = 'a' => TRUE
-- b => 'b' = 'a' => FALSE
-- NULL => NULL = 'a' => NULL
/*-------*
| entry |
+-------+
| a |
*-------*/
SELECT entry FROM entry_table WHERE NOT (entry = 'a')
-- a => NOT('a' = 'a') => NOT(TRUE) => FALSE
-- b => NOT('b' = 'a') => NOT(FALSE) => TRUE
-- NULL => NOT(NULL = 'a') => NOT(NULL) => NULL
/*-------*
| entry |
+-------+
| b |
| c |
*-------*/
SELECT entry FROM entry_table WHERE entry IS NULL
-- a => 'a' IS NULL => FALSE
-- b => 'b' IS NULL => FALSE
-- NULL => NULL IS NULL => TRUE
/*-------*
| entry |
+-------+
| NULL |
*-------*/
Comparison operators
Compares operands and produces the results of the comparison as a BOOL
value. These comparison operators are available:
Name | Syntax | Description |
---|---|---|
Less Than | X < Y |
Returns TRUE if X is less than Y .
This operator supports specifying collation.
|
Less Than or Equal To | X <= Y |
Returns TRUE if X is less than or equal to
Y .
This operator supports specifying collation.
|
Greater Than | X > Y |
Returns TRUE if X is greater than
Y .
This operator supports specifying collation.
|
Greater Than or Equal To | X >= Y |
Returns TRUE if X is greater than or equal to
Y .
This operator supports specifying collation.
|
Equal | X = Y |
Returns TRUE if X is equal to Y .
This operator supports specifying collation.
|
Not Equal | X != Y X <> Y |
Returns TRUE if X is not equal to
Y .
This operator supports specifying collation.
|
BETWEEN |
X [NOT] BETWEEN Y AND Z |
Returns |
LIKE |
X [NOT] LIKE Y |
See the `LIKE` operator for details. |
IN |
Multiple | See the `IN` operator for details. |
The following rules apply to operands in a comparison operator:
- The operands must be comparable.
- A comparison operator generally requires both operands to be of the same type.
- If the operands are of different types, and the values of those types can be converted to a common type without loss of precision, they are generally coerced to that common type for the comparison.
- A literal operand is generally coerced to the same data type of a non-literal operand that is part of the comparison.
- Struct operands support only these comparison operators: equal
(
=
), not equal (!=
and<>
), andIN
.
The following rules apply when comparing these data types:
FLOAT64
: All comparisons withNaN
returnFALSE
, except for!=
and<>
, which returnTRUE
.BOOL
:FALSE
is less thanTRUE
.STRING
: Strings are compared codepoint-by-codepoint, which means that canonically equivalent strings are only guaranteed to compare as equal if they have been normalized first.JSON
: You can't compare JSON, but you can compare the values inside of JSON if you convert the values to SQL values first. For more information, seeJSON
functions.NULL
: Any operation with aNULL
input returnsNULL
.STRUCT
: When testing a struct for equality, it's possible that one or more fields areNULL
. In such cases:- If all non-
NULL
field values are equal, the comparison returnsNULL
. - If any non-
NULL
field values are not equal, the comparison returnsFALSE
.
The following table demonstrates how
STRUCT
data types are compared when they have fields that areNULL
valued.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
- If all non-
EXISTS
operator
EXISTS ( subquery )
Description
Returns TRUE
if the subquery produces one or more rows. Returns FALSE
if
the subquery produces zero rows. Never returns NULL
. To learn more about
how you can use a subquery with EXISTS
,
see EXISTS
subqueries.
Examples
In this example, the EXISTS
operator returns FALSE
because there are no
rows in Words
where the direction is south
:
WITH Words AS (
SELECT 'Intend' as value, 'east' as direction UNION ALL
SELECT 'Secure', 'north' UNION ALL
SELECT 'Clarity', 'west'
)
SELECT EXISTS ( SELECT value FROM Words WHERE direction = 'south' ) as result;
/*--------*
| result |
+--------+
| FALSE |
*--------*/
IN
operator
The IN
operator supports the following syntax:
search_value [NOT] IN value_set
value_set:
{
(expression[, ...])
| (subquery)
| UNNEST(array_expression)
}
Description
Checks for an equal value in a set of values.
Semantic rules apply, but in general, IN
returns TRUE
if an equal value is found, FALSE
if an equal value is excluded, otherwise
NULL
. NOT IN
returns FALSE
if an equal value is found, TRUE
if an
equal value is excluded, otherwise NULL
.
search_value
: The expression that is compared to a set of values.value_set
: One or more values to compare to a search value.(expression[, ...])
: A list of expressions.(subquery)
: A subquery that returns a single column. The values in that column are the set of values. If no rows are produced, the set of values is empty.UNNEST(array_expression)
: An UNNEST operator that returns a column of values from an array expression. This is equivalent to:IN (SELECT element FROM UNNEST(array_expression) AS element)
This operator supports collation, but these limitations apply:
[NOT] IN UNNEST
does not support collation.- If collation is used with a list of expressions, there must be at least one item in the list.
Semantic rules
When using the IN
operator, the following semantics apply in this order:
- Returns
FALSE
ifvalue_set
is empty. - Returns
NULL
ifsearch_value
isNULL
. - Returns
TRUE
ifvalue_set
contains a value equal tosearch_value
. - Returns
NULL
ifvalue_set
contains aNULL
. - Returns
FALSE
.
When using the NOT IN
operator, the following semantics apply in this order:
- Returns
TRUE
ifvalue_set
is empty. - Returns
NULL
ifsearch_value
isNULL
. - Returns
FALSE
ifvalue_set
contains a value equal tosearch_value
. - Returns
NULL
ifvalue_set
contains aNULL
. - Returns
TRUE
.
The semantics of:
x IN (y, z, ...)
are defined as equivalent to:
(x = y) OR (x = z) OR ...
and the subquery and array forms are defined similarly.
x NOT IN ...
is equivalent to:
NOT(x IN ...)
The UNNEST
form treats an array scan like UNNEST
in the
FROM
clause:
x [NOT] IN UNNEST(<array expression>)
This form is often used with array parameters. For example:
x IN UNNEST(@array_parameter)
See the Arrays topic for more information on how to use this syntax.
IN
can be used with multi-part keys by using the struct constructor syntax.
For example:
(Key1, Key2) IN ( (12,34), (56,78) )
(Key1, Key2) IN ( SELECT (table.a, table.b) FROM table )
See the Struct Type topic for more information.
Return Data Type
BOOL
Examples
You can use these WITH
clauses to emulate temporary tables for
Words
and Items
in the following examples:
WITH Words AS (
SELECT 'Intend' as value UNION ALL
SELECT 'Secure' UNION ALL
SELECT 'Clarity' UNION ALL
SELECT 'Peace' UNION ALL
SELECT 'Intend'
)
SELECT * FROM Words;
/*----------*
| value |
+----------+
| Intend |
| Secure |
| Clarity |
| Peace |
| Intend |
*----------*/
WITH
Items AS (
SELECT STRUCT('blue' AS color, 'round' AS shape) AS info UNION ALL
SELECT STRUCT('blue', 'square') UNION ALL
SELECT STRUCT('red', 'round')
)
SELECT * FROM Items;
/*----------------------------*
| info |
+----------------------------+
| {blue color, round shape} |
| {blue color, square shape} |
| {red color, round shape} |
*----------------------------*/
Example with IN
and an expression:
SELECT * FROM Words WHERE value IN ('Intend', 'Secure');
/*----------*
| value |
+----------+
| Intend |
| Secure |
| Intend |
*----------*/
Example with NOT IN
and an expression:
SELECT * FROM Words WHERE value NOT IN ('Intend');
/*----------*
| value |
+----------+
| Secure |
| Clarity |
| Peace |
*----------*/
Example with IN
, a scalar subquery, and an expression:
SELECT * FROM Words WHERE value IN ((SELECT 'Intend'), 'Clarity');
/*----------*
| value |
+----------+
| Intend |
| Clarity |
| Intend |
*----------*/
Example with IN
and an UNNEST
operation:
SELECT * FROM Words WHERE value IN UNNEST(['Secure', 'Clarity']);
/*----------*
| value |
+----------+
| Secure |
| Clarity |
*----------*/
Example with IN
and a struct:
SELECT
(SELECT AS STRUCT Items.info) as item
FROM
Items
WHERE (info.shape, info.color) IN (('round', 'blue'));
/*------------------------------------*
| item |
+------------------------------------+
| { {blue color, round shape} info } |
*------------------------------------*/
IS
operators
IS operators return TRUE or FALSE for the condition they are testing. They never
return NULL
, even for NULL
inputs, unlike the IS_INF
and IS_NAN
functions defined in Mathematical Functions.
If NOT
is present, the output BOOL
value is
inverted.
Function Syntax | Input Data Type | Result Data Type | Description |
---|---|---|---|
X IS TRUE |
BOOL |
BOOL |
Evaluates to TRUE if X evaluates to
TRUE .
Otherwise, evaluates to FALSE .
|
X IS NOT TRUE |
BOOL |
BOOL |
Evaluates to FALSE if X evaluates to
TRUE .
Otherwise, evaluates to TRUE .
|
X IS FALSE |
BOOL |
BOOL |
Evaluates to TRUE if X evaluates to
FALSE .
Otherwise, evaluates to FALSE .
|
X IS NOT FALSE |
BOOL |
BOOL |
Evaluates to FALSE if X evaluates to
FALSE .
Otherwise, evaluates to TRUE .
|
X IS NULL |
Any value type | BOOL |
Evaluates to TRUE if X evaluates to
NULL .
Otherwise evaluates to FALSE .
|
X IS NOT NULL |
Any value type | BOOL |
Evaluates to FALSE if X evaluates to
NULL .
Otherwise evaluates to TRUE .
|
X IS UNKNOWN |
BOOL |
BOOL |
Evaluates to TRUE if X evaluates to
NULL .
Otherwise evaluates to FALSE .
|
X IS NOT UNKNOWN |
BOOL |
BOOL |
Evaluates to FALSE if X evaluates to
NULL .
Otherwise, evaluates to TRUE .
|
IS DISTINCT FROM
operator
expression_1 IS [NOT] DISTINCT FROM expression_2
Description
IS DISTINCT FROM
returns TRUE
if the input values are considered to be
distinct from each other by the DISTINCT
and
GROUP BY
clauses. Otherwise, returns FALSE
.
a IS DISTINCT FROM b
being TRUE
is equivalent to:
SELECT COUNT(DISTINCT x) FROM UNNEST([a,b]) x
returning2
.SELECT * FROM UNNEST([a,b]) x GROUP BY x
returning 2 rows.
a IS DISTINCT FROM b
is equivalent to NOT (a = b)
, except for the
following cases:
- This operator never returns
NULL
soNULL
values are considered to be distinct from non-NULL
values, not otherNULL
values. NaN
values are considered to be distinct from non-NaN
values, but not otherNaN
values.
You can use this operation with fields in a complex data type, but not on the complex data types themselves. These complex data types cannot be compared directly:
STRUCT
ARRAY
Input values:
expression_1
: The first value to compare. This can be a groupable data type,NULL
orNaN
.expression_2
: The second value to compare. This can be a groupable data type,NULL
orNaN
.NOT
: If present, the outputBOOL
value is inverted.
Return type
BOOL
Examples
These return TRUE
:
SELECT 1 IS DISTINCT FROM 2
SELECT 1 IS DISTINCT FROM NULL
SELECT 1 IS NOT DISTINCT FROM 1
SELECT NULL IS NOT DISTINCT FROM NULL
These return FALSE
:
SELECT NULL IS DISTINCT FROM NULL
SELECT 1 IS DISTINCT FROM 1
SELECT 1 IS NOT DISTINCT FROM 2
SELECT 1 IS NOT DISTINCT FROM NULL
LIKE
operator
expression_1 [NOT] LIKE expression_2
Description
LIKE
returns TRUE
if the string in the first operand expression_1
matches a pattern specified by the second operand expression_2
,
otherwise returns FALSE
.
NOT LIKE
returns TRUE
if the string in the first operand expression_1
does not match a pattern specified by the second operand expression_2
,
otherwise returns FALSE
.
Expressions can contain these characters:
- A percent sign (
%
) matches any number of characters or bytes. - An underscore (
_
) matches a single character or byte. - You can escape
\
,_
, or%
using two backslashes. For example,\\%
. If you are using raw strings, only a single backslash is required. For example,r'\%'
.
This operator supports collation, but caveats apply:
- Each
%
character inexpression_2
represents an arbitrary string specifier. An arbitrary string specifier can represent any sequence of0
or more characters. A character in the expression represents itself and is considered a single character specifier unless:
The character is a percent sign (
%
).The character is an underscore (
_
) and the collator is notund:ci
.
These additional rules apply to the underscore (
_
) character:If the collator is not
und:ci
, an error is produced when an underscore is not escaped inexpression_2
.If the collator is not
und:ci
, the underscore is not allowed when the operands have collation specified.Some compatibility composites, such as the fi-ligature (
fi
) and the telephone sign (℡
), will produce a match if they are compared to an underscore.A single underscore matches the idea of what a character is, based on an approximation known as a grapheme cluster.
For a contiguous sequence of single character specifiers, equality depends on the collator and its language tags and tailoring.
By default, the
und:ci
collator does not fully normalize a string. Some canonically equivalent strings are considered unequal for both the=
andLIKE
operators.The
LIKE
operator with collation has the same behavior as the=
operator when there are no wildcards in the strings.Character sequences with secondary or higher-weighted differences are considered unequal. This includes accent differences and some special cases.
For example there are three ways to produce German sharp
ß
:\u1E9E
\U00DF
ss
\u1E9E
and\U00DF
are considered equal but differ in tertiary. They are considered equal withund:ci
collation but different fromss
, which has secondary differences.Character sequences with tertiary or lower-weighted differences are considered equal. This includes case differences and kana subtype differences, which are considered equal.
There are ignorable characters defined in Unicode. Ignorable characters are ignored in the pattern matching.
Return type
BOOL
Examples
The following examples illustrate how you can check to see if the string in the first operand matches a pattern specified by the second operand.
-- Returns TRUE
SELECT 'apple' LIKE 'a%';
-- Returns FALSE
SELECT '%a' LIKE 'apple';
-- Returns FALSE
SELECT 'apple' NOT LIKE 'a%';
-- Returns TRUE
SELECT '%a' NOT LIKE 'apple';
-- Produces an error
SELECT NULL LIKE 'a%';
-- Produces an error
SELECT 'apple' LIKE NULL;
The following example illustrates how to search multiple patterns in an array
to find a match with the LIKE
operator:
WITH Words AS
(SELECT 'Intend with clarity.' as value UNION ALL
SELECT 'Secure with intention.' UNION ALL
SELECT 'Clarity and security.')
SELECT value
FROM Words WHERE
EXISTS(
SELECT value FROM UNNEST(['%ity%', '%and%']) AS pattern
WHERE value LIKE pattern
);
/*------------------------+
| value |
+------------------------+
| Intend with clarity. |
| Clarity and security. |
+------------------------*/
The following examples illustrate how collation can be used with the LIKE
operator.
-- Returns FALSE
'Foo' LIKE '%foo%'
-- Returns TRUE
COLLATE('Foo', 'und:ci') LIKE COLLATE('%foo%', 'und:ci');
-- Returns TRUE
COLLATE('Foo', 'und:ci') = COLLATE('foo', 'und:ci');
-- Produces an error
COLLATE('Foo', 'und:ci') LIKE COLLATE('%foo%', 'binary');
-- Produces an error
COLLATE('Foo', 'und:ci') LIKE COLLATE('%f_o%', 'und:ci');
-- Returns TRUE
COLLATE('Foo_', 'und:ci') LIKE COLLATE('%foo\\_%', 'und:ci');
There are two capital forms of ß
. We can use either SS
or ẞ
as upper
case. While the difference between ß
and ẞ
is case difference (tertiary
difference), the difference between sharp s
and ss
is secondary and
considered not equal using the und:ci
collator. For example:
-- Returns FALSE
'MASSE' LIKE 'Maße';
-- Returns FALSE
COLLATE('MASSE', 'und:ci') LIKE '%Maße%';
-- Returns FALSE
COLLATE('MASSE', 'und:ci') = COLLATE('Maße', 'und:ci');
The kana differences in Japanese are considered as tertiary or quaternary
differences, and should be considered as equal in the und:ci
collator with
secondary strength.
'\u3042'
is'あ'
(hiragana)'\u30A2'
is'ア'
(katakana)
For example:
-- Returns FALSE
'\u3042' LIKE '%\u30A2%';
-- Returns TRUE
COLLATE('\u3042', 'und:ci') LIKE COLLATE('%\u30A2%', 'und:ci');
-- Returns TRUE
COLLATE('\u3042', 'und:ci') = COLLATE('\u30A2', 'und:ci');
When comparing two strings, the und:ci
collator compares the collation units
based on the specification of the collation. Even though the number of
code points is different, the two strings are considered equal when the
collation units are considered the same.
'\u0041\u030A'
is'Å'
(two code points)'\u0061\u030A'
is'å'
(two code points)'\u00C5'
is'Å'
(one code point)
In the following examples, the difference between '\u0061\u030A'
and
'\u00C5'
is tertiary.
-- Returns FALSE
'\u0061\u030A' LIKE '%\u00C5%';
-- Returns TRUE
COLLATE('\u0061\u030A', 'und:ci') LIKE '%\u00C5%';
-- Returns TRUE
COLLATE('\u0061\u030A', 'und:ci') = COLLATE('\u00C5', 'und:ci');
In the following example, '\u0083'
is a NO BREAK HERE
character and
is ignored.
-- Returns FALSE
'\u0083' LIKE '';
-- Returns TRUE
COLLATE('\u0083', 'und:ci') LIKE '';
Quantified LIKE
operator
The quantified LIKE
operator supports the following syntax:
search_value [NOT] LIKE quantifier patterns
quantifier:
{ ANY | SOME | ALL }
patterns:
{
pattern_expression_list
| pattern_array
}
pattern_expression_list:
(expression[, ...])
pattern_array:
UNNEST(array_expression)
Description
Checks search_value
for matches against several patterns. Each comparison is
case-sensitive. Wildcard searches are supported.
Semantic rules apply, but in general, LIKE
returns TRUE
if a matching pattern is found, FALSE
if a matching pattern
is not found, or otherwise NULL
. NOT LIKE
returns FALSE
if a
matching pattern is found, TRUE
if a matching pattern is not found, or
otherwise NULL
.
search_value
: The value to search for matching patterns. This value can be aSTRING
orBYTES
type.patterns
: The patterns to look for in the search value. Each pattern must resolve to the same type assearch_value
.pattern_expression_list
: A list of one or more patterns that match thesearch_value
type.pattern_array
: AnUNNEST
operation that returns a column of values with the same type assearch_value
from an array expression.
The regular expressions that are supported by the
LIKE
operator are also supported bypatterns
in the quantifiedLIKE
operator.quantifier
: Condition for pattern matching.ANY
: Checks if the set of patterns contains at least one pattern that matches the search value.SOME
: Synonym forANY
.ALL
: Checks if every pattern in the set of patterns matches the search value.
Collation caveats
Collation is supported, but with the following caveats:
- The collation caveats that apply to the
LIKE
operator also apply to the quantifiedLIKE
operator. - If a collation-supported input contains no collation specification or an empty collation specification and another input contains an explicitly defined collation, the explicitly defined collation is used for all of the inputs.
- All inputs with a non-empty, explicitly defined collation specification must have the same type of collation specification, otherwise an error is thrown.
Semantics rules
When using the quantified LIKE
operator with ANY
or SOME
, the
following semantics apply in this order:
- Returns
FALSE
ifpatterns
is empty. - Returns
NULL
ifsearch_value
isNULL
. - Returns
TRUE
ifsearch_value
matches at least one value inpatterns
. - Returns
NULL
if a pattern inpatterns
isNULL
and other patterns inpatterns
don't match. - Returns
FALSE
.
When using the quantified LIKE
operator with ALL
, the following semantics
apply in this order:
- For
pattern_array
, returnsFALSE
ifpatterns
is empty. - Returns
NULL
ifsearch_value
isNULL
. - Returns
TRUE
ifsearch_value
matches all values inpatterns
. - Returns
NULL
if a pattern inpatterns
isNULL
and other patterns inpatterns
don't match. - Returns
FALSE
.
When using the quantified NOT LIKE
operator with ANY
or SOME
, the
following semantics apply in this order:
- For
pattern_array
, returnsTRUE
ifpatterns
is empty. - Returns
NULL
ifsearch_value
isNULL
. - Returns
TRUE
ifsearch_value
doesn't match at least one value inpatterns
. - Returns
NULL
if a pattern inpatterns
isNULL
and other patterns inpatterns
don't match. - Returns
FALSE
.
When using the quantified NOT LIKE
operator with ALL
, the following
semantics apply in this order:
- For
pattern_array
, returnsTRUE
ifpatterns
is empty. - Returns
NULL
ifsearch_value
isNULL
. - Returns
TRUE
ifsearch_value
matches none of the values inpatterns
. - Returns
NULL
if a pattern inpatterns
isNULL
and other patterns inpatterns
don't match. - Returns
FALSE
.
Details
Some computation limitations apply. For more information, see Quotas and limits.
Return Data Type
BOOL
Examples
The following example checks to see if the Intend%
or %intention%
pattern exists in a value and produces that value if either pattern is found:
WITH Words AS
(SELECT 'Intend with clarity.' as value UNION ALL
SELECT 'Secure with intention.' UNION ALL
SELECT 'Clarity and security.')
SELECT * FROM Words WHERE value LIKE ANY ('Intend%', '%intention%');
/*------------------------+
| value |
+------------------------+
| Intend with clarity. |
| Secure with intention. |
+------------------------*/
The following example checks to see if the %ity%
pattern exists in a value and produces that value if the pattern is found.
Example with LIKE ALL
:
WITH Words AS
(SELECT 'Intend with clarity.' as value UNION ALL
SELECT 'Secure with intention.' UNION ALL
SELECT 'Clarity and security.')
SELECT * FROM Words WHERE value LIKE ALL ('%ity%');
/*-----------------------+
| value |
+-----------------------+
| Intend with clarity. |
| Clarity and security. |
+-----------------------*/
The following example checks to see if the %ity%
pattern exists in a value produces that value if the pattern
is not found:
WITH Words AS
(SELECT 'Intend with clarity.' as value UNION ALL
SELECT 'Secure with intention.' UNION ALL
SELECT 'Clarity and security.')
SELECT * FROM Words WHERE value NOT LIKE ('%ity%');
/*------------------------+
| value |
+------------------------+
| Secure with intention. |
+------------------------*/
You can pass in an array for patterns
. For example:
WITH Words AS
(SELECT 'Intend with clarity.' as value UNION ALL
SELECT 'Secure with intention.' UNION ALL
SELECT 'Clarity and security.')
SELECT * FROM Words WHERE value LIKE ANY UNNEST(['%ion%', '%and%']);
/*------------------------+
| value |
+------------------------+
| Secure with intention. |
| Clarity and security. |
+------------------------*/
The following queries illustrate some of the semantic rules for the
quantified LIKE
operator:
SELECT
NULL LIKE ANY ('a', 'b'), -- NULL
'a' LIKE ANY ('a', 'c'), -- TRUE
'a' LIKE ANY ('b', 'c'), -- FALSE
'a' LIKE ANY ('a', NULL), -- TRUE
'a' LIKE ANY ('b', NULL), -- NULL
NULL NOT LIKE ANY ('a', 'b'), -- NULL
'a' NOT LIKE ANY ('a', 'b'), -- TRUE
'a' NOT LIKE ANY ('a', '%a%'), -- FALSE
'a' NOT LIKE ANY ('a', NULL), -- NULL
'a' NOT LIKE ANY ('b', NULL); -- TRUE
SELECT
NULL LIKE SOME ('a', 'b'), -- NULL
'a' LIKE SOME ('a', 'c'), -- TRUE
'a' LIKE SOME ('b', 'c'), -- FALSE
'a' LIKE SOME ('a', NULL), -- TRUE
'a' LIKE SOME ('b', NULL), -- NULL
NULL NOT LIKE SOME ('a', 'b'), -- NULL
'a' NOT LIKE SOME ('a', 'b'), -- TRUE
'a' NOT LIKE SOME ('a', '%a%'), -- FALSE
'a' NOT LIKE SOME ('a', NULL), -- NULL
'a' NOT LIKE SOME ('b', NULL); -- TRUE
SELECT
NULL LIKE ALL ('a', 'b'), -- NULL
'a' LIKE ALL ('a', '%a%'), -- TRUE
'a' LIKE ALL ('a', 'c'), -- FALSE
'a' LIKE ALL ('a', NULL), -- NULL
'a' LIKE ALL ('b', NULL), -- FALSE
NULL NOT LIKE ALL ('a', 'b'), -- NULL
'a' NOT LIKE ALL ('b', 'c'), -- TRUE
'a' NOT LIKE ALL ('a', 'c'), -- FALSE
'a' NOT LIKE ALL ('a', NULL), -- FALSE
'a' NOT LIKE ALL ('b', NULL); -- NULL
The following queries illustrate some of the semantic rules for the
quantified LIKE
operator and collation:
SELECT
COLLATE('a', 'und:ci') LIKE ALL ('a', 'A'), -- TRUE
'a' LIKE ALL (COLLATE('a', 'und:ci'), 'A'), -- TRUE
'a' LIKE ALL ('%A%', COLLATE('a', 'und:ci')); -- TRUE
-- ERROR: BYTES and STRING values can't be used together.
SELECT b'a' LIKE ALL (COLLATE('a', 'und:ci'), 'A');
Concatenation operator
The concatenation operator combines multiple values into one.
Function Syntax | Input Data Type | Result Data Type |
---|---|---|
STRING || STRING [ || ... ] |
STRING |
STRING |
BYTES || BYTES [ || ... ] |
BYTES |
BYTES |
ARRAY<T> || ARRAY<T> [ || ... ] |
ARRAY<T> |
ARRAY<T> |
Conditional expressions
GoogleSQL for BigQuery supports conditional expressions. Conditional expressions impose constraints on the evaluation order of their inputs. In essence, they are evaluated left to right, with short-circuiting, and only evaluate the output value that was chosen. In contrast, all inputs to regular functions are evaluated before calling the function. Short-circuiting in conditional expressions can be exploited for error handling or performance tuning.
Expression list
Name | Summary |
---|---|
CASE expr
|
Compares the given expression to each successive WHEN clause
and produces the first result where the values are equal.
|
CASE
|
Evaluates the condition of each successive WHEN clause and
produces the first result where the condition evaluates to
TRUE .
|
COALESCE
|
Produces the value of the first non-NULL expression, if any,
otherwise NULL .
|
IF
|
If an expression evaluates to TRUE , produces a specified
result, otherwise produces the evaluation for an else result.
|
IFNULL
|
If an expression evaluates to NULL , produces a specified
result, otherwise produces the expression.
|
NULLIF
|
Produces NULL if the first expression that matches another
evaluates to TRUE , otherwise returns the first expression.
|
CASE expr
CASE expr
WHEN expr_to_match THEN result
[ ... ]
[ ELSE else_result ]
END
Description
Compares expr
to expr_to_match
of each successive WHEN
clause and returns
the first result where this comparison evaluates to TRUE
. The remaining WHEN
clauses and else_result
aren't evaluated.
If the expr = expr_to_match
comparison evaluates to FALSE
or NULL
for all
WHEN
clauses, returns the evaluation of else_result
if present; if
else_result
isn't present, then returns NULL
.
Consistent with equality comparisons elsewhere, if both
expr
and expr_to_match
are NULL
, then expr = expr_to_match
evaluates to
NULL
, which returns else_result
. If a CASE statement needs to distinguish a
NULL
value, then the alternate CASE syntax should be used.
expr
and expr_to_match
can be any type. They must be implicitly
coercible to a common supertype; equality comparisons are
done on coerced values. There may be multiple result
types. result
and
else_result
expressions must be coercible to a common supertype.
This expression supports specifying collation.
Return Data Type
Supertype of result
[, ...] and else_result
.
Example
WITH Numbers AS (
SELECT 90 as A, 2 as B UNION ALL
SELECT 50, 8 UNION ALL
SELECT 60, 6 UNION ALL
SELECT 50, 10
)
SELECT
A,
B,
CASE A
WHEN 90 THEN 'red'
WHEN 50 THEN 'blue'
ELSE 'green'
END
AS result
FROM Numbers
/*------------------*
| A | B | result |
+------------------+
| 90 | 2 | red |
| 50 | 8 | blue |
| 60 | 6 | green |
| 50 | 10 | blue |
*------------------*/
CASE
CASE
WHEN condition THEN result
[ ... ]
[ ELSE else_result ]
END
Description
Evaluates the condition of each successive WHEN
clause and returns the
first result where the condition evaluates to TRUE
; any remaining WHEN
clauses and else_result
aren't evaluated.
If all conditions evaluate to FALSE
or NULL
, returns evaluation of
else_result
if present; if else_result
isn't present, then returns NULL
.
For additional rules on how values are evaluated, see the three-valued logic table in Logical operators.
condition
must be a boolean expression. There may be multiple result
types.
result
and else_result
expressions must be implicitly coercible to a common
supertype.
This expression supports specifying collation.
Return Data Type
Supertype of result
[, ...] and else_result
.
Example
WITH Numbers AS (
SELECT 90 as A, 2 as B UNION ALL
SELECT 50, 6 UNION ALL
SELECT 20, 10
)
SELECT
A,
B,
CASE
WHEN A > 60 THEN 'red'
WHEN B = 6 THEN 'blue'
ELSE 'green'
END
AS result
FROM Numbers
/*------------------*
| A | B | result |
+------------------+
| 90 | 2 | red |
| 50 | 6 | blue |
| 20 | 10 | green |
*------------------*/
COALESCE
COALESCE(expr[, ...])
Description
Returns the value of the first non-NULL
expression, if any, otherwise
NULL
. The remaining expressions aren't evaluated. An input expression can be
any type. There may be multiple input expression types.
All input expressions must be implicitly coercible to a common
supertype.
Return Data Type
Supertype of expr
[, ...].
Examples
SELECT COALESCE('A', 'B', 'C') as result
/*--------*
| result |
+--------+
| A |
*--------*/
SELECT COALESCE(NULL, 'B', 'C') as result
/*--------*
| result |
+--------+
| B |
*--------*/
IF
IF(expr, true_result, else_result)
Description
If expr
evaluates to TRUE
, returns true_result
, else returns the
evaluation for else_result
. else_result
isn't evaluated if expr
evaluates
to TRUE
. true_result
isn't evaluated if expr
evaluates to FALSE
or
NULL
.
expr
must be a boolean expression. true_result
and else_result
must be coercible to a common supertype.
Return Data Type
Supertype of true_result
and else_result
.
Examples
SELECT
10 AS A,
20 AS B,
IF(10 < 20, 'true', 'false') AS result
/*------------------*
| A | B | result |
+------------------+
| 10 | 20 | true |
*------------------*/
SELECT
30 AS A,
20 AS B,
IF(30 < 20, 'true', 'false') AS result
/*------------------*
| A | B | result |
+------------------+
| 30 | 20 | false |
*------------------*/
IFNULL
IFNULL(expr, null_result)
Description
If expr
evaluates to NULL
, returns null_result
. Otherwise, returns
expr
. If expr
doesn't evaluate to NULL
, null_result
isn't evaluated.
expr
and null_result
can be any type and must be implicitly coercible to
a common supertype. Synonym for
COALESCE(expr, null_result)
.
Return Data Type
Supertype of expr
or null_result
.
Examples
SELECT IFNULL(NULL, 0) as result
/*--------*
| result |
+--------+
| 0 |
*--------*/
SELECT IFNULL(10, 0) as result
/*--------*
| result |
+--------+
| 10 |
*--------*/
NULLIF
NULLIF(expr, expr_to_match)
Description
Returns NULL
if expr = expr_to_match
evaluates to TRUE
, otherwise
returns expr
.
expr
and expr_to_match
must be implicitly coercible to a
common supertype, and must be comparable.
This expression supports specifying collation.
Return Data Type
Supertype of expr
and expr_to_match
.
Example
SELECT NULLIF(0, 0) as result
/*--------*
| result |
+--------+
| NULL |
*--------*/
SELECT NULLIF(10, 0) as result
/*--------*
| result |
+--------+
| 10 |
*--------*/
FUNCTIONS
AEAD encryption functions
GoogleSQL for BigQuery supports the following AEAD encryption functions. For a description of how the AEAD encryption functions work, see AEAD encryption concepts.
Function list
Name | Summary |
---|---|
AEAD.DECRYPT_BYTES
|
Uses the matching key from a keyset to decrypt a
BYTES ciphertext.
|
AEAD.DECRYPT_STRING
|
Uses the matching key from a keyset to decrypt a BYTES
ciphertext into a STRING plaintext.
|
AEAD.ENCRYPT
|
Encrypts STRING plaintext, using the primary cryptographic key
in a keyset.
|
DETERMINISTIC_DECRYPT_BYTES
|
Uses the matching key from a keyset to decrypt a BYTES
ciphertext, using deterministic AEAD.
|
DETERMINISTIC_DECRYPT_STRING
|
Uses the matching key from a keyset to decrypt a BYTES
ciphertext into a STRING plaintext, using deterministic AEAD.
|
DETERMINISTIC_ENCRYPT
|
Encrypts STRING plaintext, using the primary cryptographic key
in a keyset, using deterministic AEAD encryption.
|
KEYS.ADD_KEY_FROM_RAW_BYTES
|
Adds a key to a keyset, and return the new keyset as a serialized
BYTES value.
|
KEYS.KEYSET_CHAIN
|
Produces a Tink keyset that is encrypted with a Cloud KMS key. |
KEYS.KEYSET_FROM_JSON
|
Converts a STRING JSON keyset to a serialized
BYTES value.
|
KEYS.KEYSET_LENGTH
|
Gets the number of keys in the provided keyset. |
KEYS.KEYSET_TO_JSON
|
Gets a JSON STRING representation of a keyset.
|
KEYS.NEW_KEYSET
|
Gets a serialized keyset containing a new key based on the key type. |
KEYS.NEW_WRAPPED_KEYSET
|
Creates a new keyset and encrypts it with a Cloud KMS key. |
KEYS.REWRAP_KEYSET
|
Re-encrypts a wrapped keyset with a new Cloud KMS key. |
KEYS.ROTATE_KEYSET
|
Adds a new primary cryptographic key to a keyset, based on the key type. |
KEYS.ROTATE_WRAPPED_KEYSET
|
Rewraps a keyset and rotates it. |
AEAD.DECRYPT_BYTES
AEAD.DECRYPT_BYTES(keyset, ciphertext, additional_data)
Description
Uses the matching key from keyset
to decrypt ciphertext
and verifies the
integrity of the data using additional_data
. Returns an error if decryption or
verification fails.
keyset
is a serialized BYTES
value returned by one of the
KEYS
functions or a STRUCT
returned by
KEYS.KEYSET_CHAIN
. keyset
must contain the key that was used to
encrypt ciphertext
, and the key must be in an 'ENABLED'
state, or else the
function returns an error. AEAD.DECRYPT_BYTES
identifies the matching key
in keyset
by finding the key with the key ID that matches the one encrypted in
ciphertext
.
ciphertext
is a BYTES
value that is the result of
a call to AEAD.ENCRYPT
where the input plaintext
was of type
BYTES
.
If ciphertext
includes an initialization vector (IV),
it should be the first bytes of ciphertext
. If ciphertext
includes an
authentication tag, it should be the last bytes of ciphertext
. If the
IV and authentic tag are one (SIV), it should be the first bytes of
ciphertext
. The IV and authentication tag commonly require 16 bytes, but may
vary in size.
additional_data
is a STRING
or BYTES
value that binds the ciphertext to
its context. This forces the ciphertext to be decrypted in the same context in
which it was encrypted. This function casts any
STRING
value to BYTES
.
This must be the same as the additional_data
provided to AEAD.ENCRYPT
to
encrypt ciphertext
, ignoring its type, or else the function returns an error.
Return Data Type
BYTES
Example
This example creates a table of unique IDs with associated plaintext values and
keysets. Then it uses these keysets to encrypt the plaintext values as
BYTES
and store them in a new table. Finally, it
uses AEAD.DECRYPT_BYTES
to decrypt the encrypted values and display them as
plaintext.
The following statement creates a table CustomerKeysets
containing a column of
unique IDs, a column of AEAD_AES_GCM_256
keysets, and a column of favorite
animals.
CREATE TABLE aead.CustomerKeysets AS
SELECT
1 AS customer_id,
KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
b'jaguar' AS favorite_animal
UNION ALL
SELECT
2 AS customer_id,
KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
b'zebra' AS favorite_animal
UNION ALL
SELECT
3 AS customer_id,
KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
b'nautilus' AS favorite_animal;
The following statement creates a table EncryptedCustomerData
containing a
column of unique IDs and a column of ciphertext. The statement encrypts the
plaintext favorite_animal
using the keyset value from CustomerKeysets
corresponding to each unique ID.
CREATE TABLE aead.EncryptedCustomerData AS
SELECT
customer_id,
AEAD.ENCRYPT(keyset, favorite_animal, CAST(CAST(customer_id AS STRING) AS BYTES))
AS encrypted_animal
FROM
aead.CustomerKeysets AS ck;
The following query uses the keysets in the CustomerKeysets
table to decrypt
data in the EncryptedCustomerData
table.
SELECT
ecd.customer_id,
AEAD.DECRYPT_BYTES(
(SELECT ck.keyset
FROM aead.CustomerKeysets AS ck
WHERE ecd.customer_id = ck.customer_id),
ecd.encrypted_animal,
CAST(CAST(customer_id AS STRING) AS BYTES)
) AS favorite_animal
FROM aead.EncryptedCustomerData AS ecd;
AEAD.DECRYPT_STRING
AEAD.DECRYPT_STRING(keyset, ciphertext, additional_data)
Description
Like AEAD.DECRYPT_BYTES
, but where additional_data
is
of type STRING
.
Return Data Type
STRING
AEAD.ENCRYPT
AEAD.ENCRYPT(keyset, plaintext, additional_data)
Description
Encrypts plaintext
using the primary cryptographic key in keyset
. The
algorithm of the primary key must be AEAD_AES_GCM_256
. Binds the ciphertext to
the context defined by additional_data
. Returns NULL
if any input is NULL
.
keyset
is a serialized BYTES
value returned by one of the
KEYS
functions or a STRUCT
returned by
KEYS.KEYSET_CHAIN
.
plaintext
is the STRING
or
BYTES
value to be encrypted.
additional_data
is a STRING
or BYTES
value that binds the ciphertext to
its context. This forces the ciphertext to be decrypted in the same context in
which it was encrypted. plaintext
and additional_data
must be of the same
type. AEAD.ENCRYPT(keyset, string1, string2)
is equivalent to
AEAD.ENCRYPT(keyset, CAST(string1 AS BYTES), CAST(string2 AS BYTES))
.
The output is ciphertext BYTES
. The ciphertext contains a
Tink-specific prefix indicating the key used to perform the encryption.
Return Data Type
BYTES
Example
The following query uses the keysets for each customer_id
in the
CustomerKeysets
table to encrypt the value of the plaintext favorite_animal
in the PlaintextCustomerData
table corresponding to that customer_id
. The
output contains a column of customer_id
values and a column of
corresponding ciphertext output as BYTES
.
WITH CustomerKeysets AS (
SELECT 1 AS customer_id, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset UNION ALL
SELECT 2, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') UNION ALL
SELECT 3, KEYS.NEW_KEYSET('AEAD_AES_GCM_256')
), PlaintextCustomerData AS (
SELECT 1 AS customer_id, 'elephant' AS favorite_animal UNION ALL
SELECT 2, 'walrus' UNION ALL
SELECT 3, 'leopard'
)
SELECT
pcd.customer_id,
AEAD.ENCRYPT(
(SELECT keyset
FROM CustomerKeysets AS ck
WHERE ck.customer_id = pcd.customer_id),
pcd.favorite_animal,
CAST(pcd.customer_id AS STRING)
) AS encrypted_animal
FROM PlaintextCustomerData AS pcd;
DETERMINISTIC_DECRYPT_BYTES
DETERMINISTIC_DECRYPT_BYTES(keyset, ciphertext, additional_data)
Description
Uses the matching key from keyset
to decrypt ciphertext
and verifies the
integrity of the data using additional_data
. Returns an error if decryption
fails.
keyset
is a serialized BYTES
value or a STRUCT
value returned by one of the KEYS
functions. keyset
must contain
the key that was used to encrypt ciphertext
, the key must be in an 'ENABLED'
state, and the key must be of type DETERMINISTIC_AEAD_AES_SIV_CMAC_256
, or
else the function returns an error. DETERMINISTIC_DECRYPT_BYTES
identifies the
matching key in keyset
by finding the key with the key ID that matches the one
encrypted in ciphertext
.
ciphertext
is a BYTES
value that is the result of a call to
DETERMINISTIC_ENCRYPT
where the input plaintext
was of type BYTES
.
The ciphertext must follow Tink's wire format. The first
byte of ciphertext
should contain a Tink key version followed by a 4 byte key
hint. If ciphertext
includes an initialization vector (IV), it should be the
next bytes of ciphertext
. If ciphertext
includes an authentication tag, it
should be the last bytes of ciphertext
. If the IV and authentic tag are one
(SIV), it should be the first bytes of ciphertext
. The IV and authentication
tag commonly require 16 bytes, but may vary in size.
additional_data
is a STRING
or BYTES
value that binds the ciphertext to
its context. This forces the ciphertext to be decrypted in the same context in
which it was encrypted. This function casts any STRING
value to BYTES
. This
must be the same as the additional_data
provided to DETERMINISTIC_ENCRYPT
to
encrypt ciphertext
, ignoring its type, or else the function returns an error.
Return Data Type
BYTES
Example
This example creates a table of unique IDs with associated plaintext values and
keysets. Then it uses these keysets to encrypt the plaintext values as BYTES
and store them in a new table. Finally, it uses DETERMINISTIC_DECRYPT_BYTES
to
decrypt the encrypted values and display them as plaintext.
The following statement creates a table CustomerKeysets
containing a column of
unique IDs, a column of DETERMINISTIC_AEAD_AES_SIV_CMAC_256
keysets, and a
column of favorite animals.
CREATE TABLE deterministic.CustomerKeysets AS
SELECT
1 AS customer_id,
KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') AS keyset,
b'jaguar' AS favorite_animal
UNION ALL
SELECT
2 AS customer_id,
KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') AS keyset,
b'zebra' AS favorite_animal
UNION ALL
SELECT
3 AS customer_id,
KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') AS keyset,
b'nautilus' AS favorite_animal;
The following statement creates a table EncryptedCustomerData
containing a
column of unique IDs and a column of ciphertext. The statement encrypts the
plaintext favorite_animal
using the keyset value from CustomerKeysets
corresponding to each unique ID.
CREATE TABLE deterministic.EncryptedCustomerData AS
SELECT
customer_id,
DETERMINISTIC_ENCRYPT(ck.keyset, favorite_animal, CAST(CAST(customer_id AS STRING) AS BYTES))
AS encrypted_animal
FROM
deterministic.CustomerKeysets AS ck;
The following query uses the keysets in the CustomerKeysets
table to decrypt
data in the EncryptedCustomerData
table.
SELECT
ecd.customer_id,
DETERMINISTIC_DECRYPT_BYTES(
(SELECT ck.keyset
FROM deterministic.CustomerKeysets AS ck
WHERE ecd.customer_id = ck.customer_id),
ecd.encrypted_animal,
CAST(CAST(ecd.customer_id AS STRING) AS BYTES)
) AS favorite_animal
FROM deterministic.EncryptedCustomerData AS ecd;
DETERMINISTIC_DECRYPT_STRING
DETERMINISTIC_DECRYPT_STRING(keyset, ciphertext, additional_data)
Description
Like DETERMINISTIC_DECRYPT_BYTES
, but where
plaintext
is of type STRING
.
Return Data Type
STRING
DETERMINISTIC_ENCRYPT
DETERMINISTIC_ENCRYPT(keyset, plaintext, additional_data)
Description
Encrypts plaintext
using the primary cryptographic key in keyset
using
deterministic AEAD. The algorithm of the primary key must
be DETERMINISTIC_AEAD_AES_SIV_CMAC_256
. Binds the ciphertext to the context
defined by additional_data
. Returns NULL
if any input is NULL
.
keyset
is a serialized BYTES
value or a STRUCT
value returned by one of the KEYS
functions.
plaintext
is the STRING
or BYTES
value to be encrypted.
additional_data
is a STRING
or BYTES
value that binds the ciphertext to
its context. This forces the ciphertext to be decrypted in the same context in
which it was encrypted. plaintext
and additional_data
must be of the same
type. DETERMINISTIC_ENCRYPT(keyset, string1, string2)
is equivalent to
DETERMINISTIC_ENCRYPT(keyset, CAST(string1 AS BYTES), CAST(string2 AS BYTES))
.
The output is ciphertext BYTES
. The ciphertext contains a
Tink-specific prefix indicating the key used to perform the encryption.
Given an identical keyset
and plaintext
, this function returns the same
ciphertext each time it is invoked (including across queries).
Return Data Type
BYTES
Example
The following query uses the keysets for each customer_id
in the
CustomerKeysets
table to encrypt the value of the plaintext favorite_animal
in the PlaintextCustomerData
table corresponding to that customer_id
. The
output contains a column of customer_id
values and a column of corresponding
ciphertext output as BYTES
.
WITH CustomerKeysets AS (
SELECT 1 AS customer_id,
KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') AS keyset UNION ALL
SELECT 2, KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') UNION ALL
SELECT 3, KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256')
), PlaintextCustomerData AS (
SELECT 1 AS customer_id, 'elephant' AS favorite_animal UNION ALL
SELECT 2, 'walrus' UNION ALL
SELECT 3, 'leopard'
)
SELECT
pcd.customer_id,
DETERMINISTIC_ENCRYPT(
(SELECT keyset
FROM CustomerKeysets AS ck
WHERE ck.customer_id = pcd.customer_id),
pcd.favorite_animal,
CAST(pcd.customer_id AS STRING)
) AS encrypted_animal
FROM PlaintextCustomerData AS pcd;
KEYS.ADD_KEY_FROM_RAW_BYTES
KEYS.ADD_KEY_FROM_RAW_BYTES(keyset, key_type, raw_key_bytes)
Description
Returns a serialized keyset as BYTES
with the
addition of a key to keyset
based on key_type
and raw_key_bytes
.
The primary cryptographic key remains the same as in keyset
. The expected
length of raw_key_bytes
depends on the value of key_type
. The following are
supported key_types
:
'AES_CBC_PKCS'
: Creates a key for AES decryption using cipher block chaining and PKCS padding.raw_key_bytes
is expected to be a raw keyBYTES
value of length 16, 24, or 32; these lengths have sizes of 128, 192, and 256 bits, respectively. GoogleSQL AEAD functions do not support keys of these types for encryption; instead, prefer'AEAD_AES_GCM_256'
or'AES_GCM'
keys.'AES_GCM'
: Creates a key for AES decryption or encryption using Galois/Counter Mode.raw_key_bytes
must be a raw keyBYTES
value of length 16 or 32; these lengths have sizes of 128 and 256 bits, respectively. When keys of this type are inputs toAEAD.ENCRYPT
, the output ciphertext does not have a Tink-specific prefix indicating which key was used as input.
Return Data Type
BYTES
Example
The following query creates a table of customer IDs along with raw key bytes,
called CustomerRawKeys
, and a table of unique IDs, called CustomerIds
. It
creates a new 'AEAD_AES_GCM_256'
keyset for each customer_id
; then it adds a
new key to each keyset, using the raw_key_bytes
value corresponding to that
customer_id
. The output is a table where each row contains a customer_id
and
a keyset in BYTES
, which contains the raw key added
using KEYS.ADD_KEY_FROM_RAW_BYTES.
WITH CustomerRawKeys AS (
SELECT 1 AS customer_id, b'0123456789012345' AS raw_key_bytes UNION ALL
SELECT 2, b'9876543210543210' UNION ALL
SELECT 3, b'0123012301230123'
), CustomerIds AS (
SELECT 1 AS customer_id UNION ALL
SELECT 2 UNION ALL
SELECT 3
)
SELECT
ci.customer_id,
KEYS.ADD_KEY_FROM_RAW_BYTES(
KEYS.NEW_KEYSET('AEAD_AES_GCM_256'),
'AES_CBC_PKCS',
(SELECT raw_key_bytes FROM CustomerRawKeys AS crk
WHERE crk.customer_id = ci.customer_id)
) AS keyset
FROM CustomerIds AS ci;
The output keysets each contain two things: the primary cryptographic key
created using KEYS.NEW_KEYSET('AEAD_AES_GCM_256')
, and the raw key added using
KEYS.ADD_KEY_FROM_RAW_BYTES
. If a keyset in the output is used with
AEAD.ENCRYPT
, GoogleSQL uses the primary cryptographic key created
using KEYS.NEW_KEYSET('AEAD_AES_GCM_256')
to encrypt the input plaintext. If
the keyset is used with AEAD.DECRYPT_STRING
or AEAD.DECRYPT_BYTES
,
GoogleSQL returns the resulting plaintext if either key succeeds in
decrypting the ciphertext.
KEYS.KEYSET_CHAIN
KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset)
Description
Can be used in place of the keyset
argument to the AEAD
and deterministic
encryption functions to pass a Tink keyset that is encrypted
with a Cloud KMS key. This function lets you use
other AEAD functions without including plaintext keys in a query.
This function takes the following arguments:
kms_resource_name
: ASTRING
literal that contains the resource path to the Cloud KMS key that's used to decryptfirst_level_keyset
. This key must reside in the same Cloud region where this function is executed. A Cloud KMS key looks like this:gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key
first_level_keyset
: ABYTES
literal that represents a keyset or wrapped keyset.
Return Data Type
STRUCT
Example
This example creates a table of example data, then shows how to encrypt that data using a wrapped (encrypted) keyset. Finally it shows how to query the encrypted version of the data.
The following statement creates a table RawCustomerData
containing a column of
customer ids and a column of favorite animals.
CREATE TABLE aead.RawCustomerData AS
SELECT
1 AS customer_id,
b'jaguar' AS favorite_animal
UNION ALL
SELECT
2 AS customer_id,
b'zebra' AS favorite_animal
UNION ALL
SELECT
3 AS customer_id,
b'zebra' AS favorite_animal;
The following statement creates a table EncryptedCustomerData
containing a
column of unique IDs and a column of ciphertext. The statement encrypts the
plaintext favorite_animal
using the first_level_keyset provided.
DECLARE kms_resource_name STRING;
DECLARE first_level_keyset BYTES;
SET kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
SET first_level_keyset = b'\012\044\000\107\275\360\176\264\206\332\235\215\304...';
CREATE TABLE aead.EncryptedCustomerData AS
SELECT
customer_id,
AEAD.ENCRYPT(
KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
favorite_animal,
CAST(CAST(customer_id AS STRING) AS BYTES)
) AS encrypted_animal
FROM
aead.RawCustomerData;
The following query uses the first_level_keyset to decrypt data in the
EncryptedCustomerData
table.
DECLARE kms_resource_name STRING;
DECLARE first_level_keyset BYTES;
SET kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
SET first_level_keyset = b'\012\044\000\107\275\360\176\264\206\332\235\215\304...';
SELECT
customer_id,
AEAD.DECRYPT_BYTES(
KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
encrypted_animal,
CAST(CAST(customer_id AS STRING) AS BYTES)
) AS favorite_animal
FROM
aead.EncryptedCustomerData;
The previous two steps also work with the DETERMINISTIC_ENCRYPT
and
DETERMINISTIC_DECRYPT_BYTES
functions. The wrapped keyset must be created
using the DETERMINISTIC_AEAD_AES_SIV_CMAC_256
type.
The following statement creates a table EncryptedCustomerData
containing a
column of unique IDs and a column of ciphertext. The statement encrypts the
plaintext favorite_animal
using the first_level_keyset provided. You can see
that the ciphertext for favorite_animal
is the same for customers 2 and 3
since their plaintext favorite_animal
is the same.
DECLARE kms_resource_name STRING;
DECLARE first_level_keyset BYTES;
SET kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
SET first_level_keyset = b'\012\044\000\107\275\360\176\264\206\332\235\215\304...';
CREATE TABLE daead.EncryptedCustomerData AS
SELECT
customer_id,
DETERMINISTC_ENCRYPT(
KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
favorite_animal,
CAST(CAST(customer_id AS STRING) AS BYTES)
) AS encrypted_animal
FROM
daead.RawCustomerData;
The following query uses the first_level_keyset to decrypt data in the
EncryptedCustomerData
table.
DECLARE kms_resource_name STRING;
DECLARE first_level_keyset BYTES;
SET kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
SET first_level_keyset = b'\012\044\000\107\275\360\176\264\206\332\235\215\304...';
SELECT
customer_id,
DETERMINISTIC_DECRYPT_BYTES(
KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
encrypted_animal,
CAST(CAST(customer_id AS STRING) AS BYTES)
) AS favorite_animal
FROM dead.EncryptedCustomerData;
KEYS.KEYSET_FROM_JSON
KEYS.KEYSET_FROM_JSON(json_keyset)
Description
Returns the input json_keyset
STRING
as
serialized BYTES
, which is a valid input for other
KEYS
and AEAD
functions. The JSON STRING
must
be compatible with the definition of the
google.crypto.tink.Keyset
protocol buffer message: the JSON keyset should be a JSON object containing
objects and name-value pairs corresponding to those in the "keyset" message in
the google.crypto.tink.Keyset definition. You can convert the output serialized
BYTES
representation back to a JSON
STRING
using KEYS.KEYSET_TO_JSON
.
Return Data Type
BYTES
Example
KEYS.KEYSET_FROM_JSON
takes JSON-formatted STRING
values like the following:
{
"key":[
{
"keyData":{
"keyMaterialType":"SYMMETRIC",
"typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
"value":"GiD80Z8kL6AP3iSNHhqseZGAIvq7TVQzClT7FQy8YwK3OQ=="
},
"keyId":3101427138,
"outputPrefixType":"TINK",
"status":"ENABLED"
}
],
"primaryKeyId":3101427138
}
The following query creates a new keyset from a JSON-formatted
STRING
json_keyset
:
SELECT KEYS.KEYSET_FROM_JSON(json_keyset);
This returns the json_keyset
serialized as BYTES
, like the following:
\x08\x9d\x8e\x85\x82\x09\x12d\x0aX\x0a0
type.googleapis.com/google.crypto.tink.AesGcmKey\x12\"\x1a qX\xe4IG\x87\x1f\xde
\xe3)+e\x98\x0a\x1c}\xfe\x88<\x12\xeb\xc1t\xb8\x83\x1a\xcd\xa8\x97\x84g\x18\x01
\x10\x01\x18\x9d\x8e\x85\x82\x09 \x01
KEYS.KEYSET_LENGTH
KEYS.KEYSET_LENGTH(keyset)
Description
Returns the number of keys in the provided keyset.
Return Data Type
INT64
Example
This example references a JSON-formatted STRING
called json_keyset
that contains two keys:
{
"primaryKeyId":1354994251,
"key":[
{
"keyData":{
"keyMaterialType":"SYMMETRIC",
"typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
"value":"GiD9sxQRgFj4aYN78vaIlxInjZkG/uvyWSY9a8GN+ELV2Q=="
},
"keyId":1354994251,
"outputPrefixType":"TINK",
"status":"ENABLED"
}
],
"key":[
{
"keyData":{
"keyMaterialType":"SYMMETRIC",
"typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
"value":"PRn76sxQRgFj4aYN00vaIlxInjZkG/uvyWSY9a2bLRm"
},
"keyId":852264701,
"outputPrefixType":"TINK",
"status":"DISABLED"
}
]
}
The following query converts json_keyset
to a keyset and then returns
the number of keys in the keyset:
SELECT KEYS.KEYSET_LENGTH(KEYS.KEYSET_FROM_JSON(json_keyset)) as key_count;
/*-----------*
| key_count |
+-----------+
| 2 |
*-----------*/
KEYS.KEYSET_TO_JSON
KEYS.KEYSET_TO_JSON(keyset)
Description
Returns a JSON STRING
representation of the input
keyset
. The returned JSON STRING
is compatible
with the definition of the
google.crypto.tink.Keyset
protocol buffer message. You can convert the JSON
STRING
representation back to
BYTES
using KEYS.KEYSET_FROM_JSON
.
Return Data Type
STRING
Example
The following query returns a new 'AEAD_AES_GCM_256'
keyset as a
JSON-formatted STRING
.
SELECT KEYS.KEYSET_TO_JSON(KEYS.NEW_KEYSET('AEAD_AES_GCM_256'));
The result is a STRING
like the following.
{
"key":[
{
"keyData":{
"keyMaterialType":"SYMMETRIC",
"typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
"value":"GiD80Z8kL6AP3iSNHhqseZGAIvq7TVQzClT7FQy8YwK3OQ=="
},
"keyId":3101427138,
"outputPrefixType":"TINK",
"status":"ENABLED"
}
],
"primaryKeyId":3101427138
}
KEYS.NEW_KEYSET
KEYS.NEW_KEYSET(key_type)
Description
Returns a serialized keyset containing a new key based on key_type
. The
returned keyset is a serialized BYTES
representation of
google.crypto.tink.Keyset
that contains a primary cryptographic key and no additional keys. You can use
the keyset with the AEAD.ENCRYPT
, AEAD.DECRYPT_BYTES
, and
AEAD.DECRYPT_STRING
functions for encryption and decryption, as well as with
the KEYS
group of key- and keyset-related functions.
key_type
is a STRING
literal representation of the type of key to create.
key_type
cannot be NULL
. key_type
can be:
AEAD_AES_GCM_256
: Creates a 256-bit key with the pseudo-random number generator provided by boringSSL. The key uses AES-GCM for encryption and decryption operations.DETERMINISTIC_AEAD_AES_SIV_CMAC_256
: Creates a 512-bitAES-SIV-CMAC
key, which contains a 256-bitAES-CTR
key and 256-bitAES-CMAC
key. TheAES-SIV-CMAC
key is created with the pseudo-random number generator provided by boringSSL. The key uses AES-SIV for encryption and decryption operations.
Return Data Type
BYTES
Example
The following query creates a keyset for each row in CustomerIds
, which can
subsequently be used to encrypt data. Each keyset contains a single encryption
key with randomly-generated key data. Each row in the output contains a
customer_id
and an 'AEAD_AES_GCM_256'
key in
BYTES
.
SELECT customer_id, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset
FROM (
SELECT 1 AS customer_id UNION ALL
SELECT 2 UNION ALL
SELECT 3
) AS CustomerIds;
KEYS.NEW_WRAPPED_KEYSET
KEYS.NEW_WRAPPED_KEYSET(kms_resource_name, key_type)
Description
Creates a new keyset and encrypts it with a
Cloud KMS key.
Returns the wrapped keyset as a BYTES
representation of google.crypto.tink.Keyset
that contains a primary cryptographic key and no additional keys.
This function takes the following arguments:
kms_resource_name
: ASTRING
literal representation of the Cloud KMS key.kms_resource_name
cannot beNULL
. The Cloud KMS key must reside in the same Cloud region where this function is executed. A Cloud KMS key looks like this:gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key
key_type
: ASTRING
literal representation of the keyset type.key_type
cannot beNULL
but can be one of the following values:AEAD_AES_GCM_256
: Creates a 256-bit key with the pseudo-random number generator provided by boringSSL. The key uses AES-GCM for encryption and decryption operations.DETERMINISTIC_AEAD_AES_SIV_CMAC_256
: Creates a 512-bitAES-SIV-CMAC
key, which contains a 256-bitAES-CTR
key and 256-bitAES-CMAC
key. TheAES-SIV-CMAC
key is created with the pseudo-random number generator provided by boringSSL. The key uses AES-SIV for encryption and decryption operations.
Return Data Type
BYTES
Example
Put the following variables above each example query that you run:
DECLARE kms_resource_name STRING;
SET kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
The following query creates a wrapped keyset, which contains the ciphertext produced by encrypting a Tink keyset with the specified Cloud KMS key. If you run the query multiple times, it generates multiple wrapped keysets, and each wrapped keyset is unique to each query that is run.
SELECT KEYS.NEW_WRAPPED_KEYSET(kms_resource_name, 'AEAD_AES_GCM_256');
Multiple calls to this function with the same arguments in one query
returns the same value. For example, the following query only creates one
wrapped keyset and returns it for each row in a table called my_table
.
SELECT
*,
KEYS.NEW_WRAPPED_KEYSET(kms_resource_name, 'AEAD_AES_GCM_256')
FROM my_table
KEYS.REWRAP_KEYSET
KEYS.REWRAP_KEYSET(source_kms_resource_name, target_kms_resource_name, wrapped_keyset)
Description
Re-encrypts a wrapped keyset with a new
Cloud KMS key. Returns the wrapped keyset as a
BYTES
representation of google.crypto.tink.Keyset
that contains a primary cryptographic key and no additional keys.
When this function is used, a wrapped keyset is decrypted by
source_kms_resource_name
and then re-encrypted by target_kms_resource_name
.
During this process, the decrypted keyset is never visible to customers.
This function takes the following arguments:
source_kms_resource_name
: ASTRING
literal representation of the Cloud KMS key you want to replace. This key must reside in the same Cloud region where this function is executed. A Cloud KMS key looks like this:gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key
target_kms_resource_name
: ASTRING
literal representation of the new Cloud KMS key that you want to use.wrapped_keyset
: ABYTES
literal representation of the keyset that you want to re-encrypt.
Return Data Type
BYTES
Example
Put the following variables above each example query that you run:
DECLARE source_kms_resource_name STRING;
DECLARE target_kms_resource_name STRING;
DECLARE wrapped_keyset BYTES;
SET source_kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
SET target_kms_resource_name = 'gcp-kms://projects/my-project/locations/another-location/keyRings/my-key-ring/cryptoKeys/my-other-crypto-key';
SET wrapped_keyset = b'\012\044\000\107\275\360\176\264\206\332\235\215\304...';
The following query rewraps a wrapped keyset. If you run the query multiple times, it generates multiple wrapped keysets, and each wrapped keyset is unique to each query that is run.
SELECT KEYS.REWRAP_KEYSET(source_kms_resource_name, target_kms_resource_name, wrapped_keyset);
Multiple calls to this function with the same arguments in one query
returns the same value. For example, the following query only creates one
wrapped keyset and returns it for each row in a table called my_table
.
SELECT
*,
KEYS.REWRAP_KEYSET(source_kms_resource_name, target_kms_resource_name, wrapped_keyset)
FROM my_table
KEYS.ROTATE_KEYSET
KEYS.ROTATE_KEYSET(keyset, key_type)
Description
Adds a new key to keyset
based on key_type
. This new key becomes the primary
cryptographic key of the new keyset. Returns the new keyset serialized as
BYTES
.
The old primary cryptographic key from the input keyset
remains an additional
key in the returned keyset.
The new key_type
must match the key type of existing keys in the keyset
.
Return Data Type
BYTES
Example
The following statement creates a table containing a column of unique
customer_id
values and 'AEAD_AES_GCM_256'
keysets. Then, it creates a new
primary cryptographic key within each keyset in the source table using
KEYS.ROTATE_KEYSET
. Each row in the output contains a customer_id
and an
'AEAD_AES_GCM_256'
keyset in BYTES
.
WITH ExistingKeysets AS (
SELECT 1 AS customer_id, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset
UNION ALL
SELECT 2, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') UNION ALL
SELECT 3, KEYS.NEW_KEYSET('AEAD_AES_GCM_256')
)
SELECT customer_id, KEYS.ROTATE_KEYSET(keyset, 'AEAD_AES_GCM_256') AS keyset
FROM ExistingKeysets;
KEYS.ROTATE_WRAPPED_KEYSET
KEYS.ROTATE_WRAPPED_KEYSET(kms_resource_name, wrapped_keyset, key_type)
Description
Takes an existing wrapped keyset and returns a rotated and
rewrapped keyset. The returned wrapped keyset is a BYTES
representation of google.crypto.tink.Keyset.
When this function is used, the wrapped keyset is decrypted,
the new key is added, and then the keyset is re-encrypted. The primary
cryptographic key from the input wrapped_keyset
remains as an
additional key in the returned keyset. During this rotation process,
the decrypted keyset is never visible to customers.
This function takes the following arguments:
kms_resource_name
: ASTRING
literal representation of the Cloud KMS key that was used to wrap the wrapped keyset. The Cloud KMS key must reside in the same Cloud region where this function is executed. A Cloud KMS key looks like this:gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key
wrapped_keyset
: ABYTES
literal representation of the existing keyset that you want to work with.key_type
: ASTRING
literal representation of the keyset type. This must match the key type of existing keys inwrapped_keyset
.
Return Data Type
BYTES
Example
Put the following variables above each example query that you run:
DECLARE kms_resource_name STRING;
DECLARE wrapped_keyset BYTES;
SET kms_resource_name = 'gcp-kms://projects/my-project/locations/us/keyRings/my-key-ring/cryptoKeys/my-crypto-key';
SET wrapped_keyset = b'\012\044\000\107\275\360\176\264\206\332\235\215\304...';
The following query rotates a wrapped keyset. If you run the query multiple times, it generates multiple wrapped keysets, and each wrapped keyset is unique to each query that is run.
SELECT KEYS.ROTATE_WRAPPED_KEYSET(kms_resource_name, wrapped_keyset, 'AEAD_AES_GCM_256');
Multiple calls to this function with the same arguments in one query
returns the same value. For example, the following query only creates one
wrapped keyset and returns it for each row in a table called my_table
.
SELECT
*,
KEYS.ROTATE_WRAPPED_KEYSET(kms_resource_name, wrapped_keyset, 'AEAD_AES_GCM_256')
FROM my_table
Aggregate functions
GoogleSQL for BigQuery supports the following general aggregate functions. To learn about the syntax for aggregate function calls, see Aggregate function calls.
Function list
Name | Summary |
---|---|
ANY_VALUE
|
Gets an expression for some row. |
ARRAY_AGG
|
Gets an array of values. |
ARRAY_CONCAT_AGG
|
Concatenates arrays and returns a single array as a result. |
AVG
|
Gets the average of non-NULL values.
|
BIT_AND
|
Performs a bitwise AND operation on an expression. |
BIT_OR
|
Performs a bitwise OR operation on an expression. |
BIT_XOR
|
Performs a bitwise XOR operation on an expression. |
COUNT
|
Gets the number of rows in the input, or the number of rows with an
expression evaluated to any value other than NULL .
|
COUNTIF
|
Gets the count of TRUE values for an expression.
|
GROUPING
|
Checks if a groupable value in the GROUP BY clause is
aggregated.
|
LOGICAL_AND
|
Gets the logical AND of all non-NULL expressions.
|
LOGICAL_OR
|
Gets the logical OR of all non-NULL expressions.
|
MAX
|
Gets the maximum non-NULL value.
|
MAX_BY
|
Synonym for ANY_VALUE(x HAVING MAX y) .
|
MIN
|
Gets the minimum non-NULL value.
|
MIN_BY
|
Synonym for ANY_VALUE(x HAVING MIN y) .
|
STRING_AGG
|
Concatenates non-NULL STRING or
BYTES values.
|
SUM
|
Gets the sum of non-NULL values.
|
ANY_VALUE
ANY_VALUE(
expression
[ HAVING { MAX | MIN } expression2 ]
)
[ OVER over_clause ]
over_clause:
{ named_window | ( [ window_specification ] ) }
window_specification:
[ named_window ]
[ PARTITION BY partition_expression [, ...] ]
[ ORDER BY expression [ { ASC | DESC } ] [, ...] ]
[ window_frame_clause ]
Description
Returns expression
for some row chosen from the group. Which row is chosen is
nondeterministic, not random. Returns NULL
when the input produces no
rows. Returns NULL
when expression
or expression2
is
NULL
for all rows in the group.
ANY_VALUE
behaves as if IGNORE NULLS
is specified;
rows for which expression
is NULL
are not considered and won't be
selected.
If the HAVING
clause is included in the ANY_VALUE
function, the
OVER
clause can't be used with this function.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
To learn more about the OVER
clause and how to use it, see
Window function calls.
Supported Argument Types
Any
Returned Data Types
Matches the input data type.
Examples
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 |
*--------+-----------*/
WITH
Store AS (
SELECT 20 AS sold, "apples" AS fruit
UNION ALL
SELECT 30 AS sold, "pears" AS fruit
UNION ALL
SELECT 30 AS sold, "bananas" AS fruit
UNION ALL
SELECT 10 AS sold, "oranges" AS fruit
)
SELECT ANY_VALUE(fruit HAVING MAX sold) AS a_highest_selling_fruit FROM Store;
/*-------------------------*
| a_highest_selling_fruit |
+-------------------------+
| pears |
*-------------------------*/
WITH
Store AS (
SELECT 20 AS sold, "apples" AS fruit
UNION ALL
SELECT 30 AS sold, "pears" AS fruit
UNION ALL
SELECT 30 AS sold, "bananas" AS fruit
UNION ALL
SELECT 10 AS sold, "oranges" AS fruit
)
SELECT ANY_VALUE(fruit HAVING MIN sold) AS a_lowest_selling_fruit FROM Store;
/*-------------------------*
| a_lowest_selling_fruit |
+-------------------------+
| oranges |
*-------------------------*/
ARRAY_AGG
ARRAY_AGG(
[ DISTINCT ]
expression
[ { IGNORE | RESPECT } NULLS ]
[ ORDER BY key [ { ASC | DESC } ] [, ... ] ]
[ LIMIT n ]
)
[ OVER over_clause ]
over_clause:
{ named_window | ( [ window_specification ] ) }
window_specification:
[ named_window ]
[ PARTITION BY partition_expression [, ...] ]
[ ORDER BY expression [ { ASC | DESC } ] [, ...] ]
[ window_frame_clause ]
Description
Returns an ARRAY of expression
values.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
If this function is used with the OVER
clause, it's part of a
window function call. In a window function call,
aggregate function clauses can't be used.
To learn more about the OVER
clause and how to use it, see
Window function calls.
An error is raised if an array in the final query result contains a NULL
element.
Supported Argument Types
All data types except ARRAY.
Returned Data Types
ARRAY
If there are zero input rows, this function returns NULL
.
Examples
SELECT ARRAY_AGG(x) AS array_agg FROM UNNEST([2, 1,-2, 3, -2, 1, 2]) AS x;
/*-------------------------*
| array_agg |
+-------------------------+
| [2, 1, -2, 3, -2, 1, 2] |
*-------------------------*/
SELECT ARRAY_AGG(DISTINCT x) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;
/*---------------*
| array_agg |
+---------------+
| [2, 1, -2, 3] |
*---------------*/
SELECT 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 ARRAY_AGG(x ORDER BY ABS(x)) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;
/*-------------------------*
| array_agg |
+-------------------------+
| [1, 1, 2, -2, -2, 2, 3] |
*-------------------------*/
SELECT ARRAY_AGG(x LIMIT 5) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;
/*-------------------*
| array_agg |
+-------------------+
| [2, 1, -2, 3, -2] |
*-------------------*/
WITH vals AS
(
SELECT 1 x UNION ALL
SELECT -2 x UNION ALL
SELECT 3 x UNION ALL
SELECT -2 x UNION ALL
SELECT 1 x
)
SELECT ARRAY_AGG(DISTINCT x ORDER BY x) as array_agg
FROM vals;
/*------------*
| array_agg |
+------------+
| [-2, 1, 3] |
*------------*/
WITH vals AS
(
SELECT 1 x, 'a' y UNION ALL
SELECT 1 x, 'b' y UNION ALL
SELECT 2 x, 'a' y UNION ALL
SELECT 2 x, 'c' y
)
SELECT x, ARRAY_AGG(y) as array_agg
FROM vals
GROUP BY x;
/*---------------*
| x | array_agg |
+---------------+
| 1 | [a, b] |
| 2 | [a, c] |
*---------------*/
SELECT
x,
ARRAY_AGG(x) OVER (ORDER BY ABS(x)) AS array_agg
FROM UNNEST([2, 1, -2, 3, -2, 1, 2]) AS x;
/*----+-------------------------*
| x | array_agg |
+----+-------------------------+
| 1 | [1, 1] |
| 1 | [1, 1] |
| 2 | [1, 1, 2, -2, -2, 2] |
| -2 | [1, 1, 2, -2, -2, 2] |
| -2 | [1, 1, 2, -2, -2, 2] |
| 2 | [1, 1, 2, -2, -2, 2] |
| 3 | [1, 1, 2, -2, -2, 2, 3] |
*----+-------------------------*/
ARRAY_CONCAT_AGG
ARRAY_CONCAT_AGG(
expression
[ ORDER BY key [ { ASC | DESC } ] [, ... ] ]
[ LIMIT n ]
)
Description
Concatenates elements from expression
of type ARRAY
, returning a single
array as a result.
This function ignores NULL
input arrays, but respects the NULL
elements in
non-NULL
input arrays. An
error is raised, however, if an array in the final query result contains a
NULL
element. Returns NULL
if there are zero input rows or
expression
evaluates to NULL
for all rows.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
Supported Argument Types
ARRAY
Returned Data Types
ARRAY
Examples
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 [1, 2, 3, 4] AS x
UNION ALL SELECT [5, 6]
UNION ALL SELECT [7, 8, 9]
);
/*-----------------------------------*
| array_concat_agg |
+-----------------------------------+
| [5, 6, 7, 8, 9, 1, 2, 3, 4] |
*-----------------------------------*/
SELECT FORMAT("%T", ARRAY_CONCAT_AGG(x LIMIT 2)) AS array_concat_agg FROM (
SELECT [1, 2, 3, 4] AS x
UNION ALL SELECT [5, 6]
UNION ALL SELECT [7, 8, 9]
);
/*--------------------------*
| array_concat_agg |
+--------------------------+
| [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 [1, 2, 3, 4] AS x
UNION ALL SELECT [5, 6]
UNION ALL SELECT [7, 8, 9]
);
/*------------------*
| array_concat_agg |
+------------------+
| [5, 6, 7, 8, 9] |
*------------------*/
AVG
AVG(
[ DISTINCT ]
expression
)
[ OVER over_clause ]
over_clause:
{ named_window | ( [ window_specification ] ) }
window_specification:
[ named_window ]
[ PARTITION BY partition_expression [, ...] ]
[ ORDER BY expression [ { ASC | DESC } ] [, ...] ]
[ window_frame_clause ]
Description
Returns the average of non-NULL
values in an aggregated group.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
This function can be used with the
AGGREGATION_THRESHOLD
clause.
If this function is used with the OVER
clause, it's part of a
window function call. In a window function call,
aggregate function clauses can't be used.
To learn more about the OVER
clause and how to use it, see
Window function calls.
AVG
can be used with differential privacy. For more information, see
Differentially private aggregate functions.
Caveats:
- If the aggregated group is empty or the argument is
NULL
for all rows in the group, returnsNULL
. - If the argument is
NaN
for any row in the group, returnsNaN
. - If the argument is
[+|-]Infinity
for any row in the group, returns either[+|-]Infinity
orNaN
. - If there is numeric overflow, produces an error.
- If a floating-point type is returned, the result is non-deterministic, which means you might receive a different result each time you use this function.
Supported Argument Types
- Any numeric input type
INTERVAL
Returned Data Types
INPUT | INT64 | NUMERIC | BIGNUMERIC | FLOAT64 | INTERVAL |
---|---|---|---|---|---|
OUTPUT | FLOAT64 | NUMERIC | BIGNUMERIC | FLOAT64 | INTERVAL |
Examples
SELECT AVG(x) as avg
FROM UNNEST([0, 2, 4, 4, 5]) as x;
/*-----*
| avg |
+-----+
| 3 |
*-----*/
SELECT AVG(DISTINCT x) AS avg
FROM UNNEST([0, 2, 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
)
Description
Performs a bitwise AND operation on expression
and returns the result.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
Supported Argument Types
- INT64
Returned Data Types
INT64
Examples
SELECT BIT_AND(x) as bit_and FROM UNNEST([0xF001, 0x00A1]) as x;
/*---------*
| bit_and |
+---------+
| 1 |
*---------*/
BIT_OR
BIT_OR(
expression
)
Description
Performs a bitwise OR operation on expression
and returns the result.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
Supported Argument Types
- INT64
Returned Data Types
INT64
Examples
SELECT BIT_OR(x) as bit_or FROM UNNEST([0xF001, 0x00A1]) as x;
/*--------*
| bit_or |
+--------+
| 61601 |
*--------*/
BIT_XOR
BIT_XOR(
[ DISTINCT ]
expression
)
Description
Performs a bitwise XOR operation on expression
and returns the result.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
Supported Argument Types
- INT64
Returned Data Types
INT64
Examples
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 over_clause]
2.
COUNT(
[ DISTINCT ]
expression
)
[ OVER over_clause ]
over_clause:
{ named_window | ( [ window_specification ] ) }
window_specification:
[ named_window ]
[ PARTITION BY partition_expression [, ...] ]
[ ORDER BY expression [ { ASC | DESC } ] [, ...] ]
[ window_frame_clause ]
Description
- Returns the number of rows in the input.
- Returns the number of rows with
expression
evaluated to any value other thanNULL
.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
This function can be used with the
AGGREGATION_THRESHOLD
clause.
To learn more about the OVER
clause and how to use it, see
Window function calls.
This function with DISTINCT supports specifying collation.
COUNT
can be used with differential privacy. For more information, see
Differentially private aggregate functions.
Supported Argument Types
expression
can be any data type. If
DISTINCT
is present, expression
can only be a data type that is
groupable.
Return Data Types
INT64
Examples
You can use the COUNT
function to return the number of rows in a table or the
number of distinct values of an expression. For example:
SELECT
COUNT(*) AS count_star,
COUNT(DISTINCT x) AS count_dist_x
FROM UNNEST([1, 4, 4, 5]) AS x;
/*------------+--------------*
| count_star | count_dist_x |
+------------+--------------+
| 4 | 3 |
*------------+--------------*/
SELECT
x,
COUNT(*) OVER (PARTITION BY MOD(x, 3)) AS count_star,
COUNT(DISTINCT x) OVER (PARTITION BY MOD(x, 3)) AS count_dist_x
FROM UNNEST([1, 4, 4, 5]) AS x;
/*------+------------+--------------*
| x | count_star | count_dist_x |
+------+------------+--------------+
| 1 | 3 | 2 |
| 4 | 3 | 2 |
| 4 | 3 | 2 |
| 5 | 1 | 1 |
*------+------------+--------------*/
SELECT
x,
COUNT(*) OVER (PARTITION BY MOD(x, 3)) AS count_star,
COUNT(x) OVER (PARTITION BY MOD(x, 3)) AS count_x
FROM UNNEST([1, 4, NULL, 4, 5]) AS x;
/*------+------------+---------*
| x | count_star | count_x |
+------+------------+---------+
| NULL | 1 | 0 |
| 1 | 3 | 3 |
| 4 | 3 | 3 |
| 4 | 3 | 3 |
| 5 | 1 | 1 |
*------+------------+---------*/
If you want to count the number of distinct values of an expression for which a certain condition is satisfied, this is one recipe that you can use:
COUNT(DISTINCT IF(condition, expression, NULL))
Here, IF
will return the value of expression
if condition
is TRUE
, or
NULL
otherwise. The surrounding COUNT(DISTINCT ...)
will ignore the NULL
values, so it will count only the distinct values of expression
for which
condition
is TRUE
.
For example, to count the number of distinct positive values of x
:
SELECT COUNT(DISTINCT IF(x > 0, x, NULL)) AS distinct_positive
FROM UNNEST([1, -2, 4, 1, -5, 4, 1, 3, -6, 1]) AS x;
/*-------------------*
| distinct_positive |
+-------------------+
| 3 |
*-------------------*/
Or to count the number of distinct dates on which a certain kind of event occurred:
WITH Events AS (
SELECT DATE '2021-01-01' AS event_date, 'SUCCESS' AS event_type
UNION ALL
SELECT DATE '2021-01-02' AS event_date, 'SUCCESS' AS event_type
UNION ALL
SELECT DATE '2021-01-02' AS event_date, 'FAILURE' AS event_type
UNION ALL
SELECT DATE '2021-01-03' AS event_date, 'SUCCESS' AS event_type
UNION ALL
SELECT DATE '2021-01-04' AS event_date, 'FAILURE' AS event_type
UNION ALL
SELECT DATE '2021-01-04' AS event_date, 'FAILURE' AS event_type
)
SELECT
COUNT(DISTINCT IF(event_type = 'FAILURE', event_date, NULL))
AS distinct_dates_with_failures
FROM Events;
/*------------------------------*
| distinct_dates_with_failures |
+------------------------------+
| 2 |
*------------------------------*/
COUNTIF
COUNTIF(
[ DISTINCT ]
expression
)
[ OVER over_clause ]
over_clause:
{ named_window | ( [ window_specification ] ) }
window_specification:
[ named_window ]
[ PARTITION BY partition_expression [, ...] ]
[ ORDER BY expression [ { ASC | DESC } ] [, ...] ]
[ window_frame_clause ]
Description
Returns the count of TRUE
values for expression
. Returns 0
if there are
zero input rows, or if expression
evaluates to FALSE
or NULL
for all rows.
Since expression
must be a BOOL
, the form COUNTIF(DISTINCT ...)
is
generally not useful: there is only one distinct value of TRUE
. So
COUNTIF(DISTINCT ...)
will return 1 if expression
evaluates to TRUE
for
one or more input rows, or 0 otherwise.
Usually when someone wants to combine COUNTIF
and DISTINCT
, they
want to count the number of distinct values of an expression for which a certain
condition is satisfied. One recipe to achieve this is the following:
COUNT(DISTINCT IF(condition, expression, NULL))
Note that this uses COUNT
, not COUNTIF
; the IF
part has been moved inside.
To learn more, see the examples for COUNT
.
To learn more about the optional aggregate clauses that you can pass into this function, see Aggregate function calls.
This function can be used with the
AGGREGATION_THRESHOLD
clause.
To learn more about the OVER
clause and how to use it, see
Window function calls.
Supported Argument Types
BOOL
Return Data Types
INT64
Examples
SELECT COUNTIF(x<0) AS num_negative, COUNTIF(x>0) AS num_positive
FROM UNNEST([5, -2, 3, 6, -10, -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([