GoogleSQL for BigQuery supports operators. Operators are represented by special characters or keywords; they don't 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 NULLwhen one of the operands isNULL.
- All operators will throw an error if the computation result overflows.
- For all floating point operations, +/-infandNaNmay only be returned if one of the operands is+/-inforNaN. 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 | STRUCTJSON | Field access operator | Binary | 
|  | Array subscript operator | ARRAY | Array position. Must be used with OFFSETorORDINAL—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, orARRAY<T> | Concatenation operator | Binary | 
|   
4 | + | All numeric types, DATEwithINT64,INTERVAL | Addition | Binary | 
|  | - | All numeric types, DATEwithINT64,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 | STRINGandBYTES | Value does [not] match the pattern specified | Binary | 
|  | Quantified LIKE | STRINGandBYTES | 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 | 
For example, the logical expression:
 x OR y AND z 
is interpreted as:
 ( x OR ( y AND z ) ) 
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 aren't associative. Therefore, parentheses are required 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, orNULL. | 
| Comparison operators | Compares operands and produces the results of the comparison as a BOOLvalue. | 
| EXISTSoperator | Checks if a subquery produces one or more rows. | 
| INoperator | Checks for an equal value in a set of values. | 
| ISoperators | Checks for the truth of a condition and produces either TRUEorFALSE. | 
| IS DISTINCT FROMoperator | Checks if values are considered to be distinct from each other. | 
| LIKEoperator | Checks if values are like or not like one another. | 
| Quantified LIKEoperator | Checks a search value for matches against several patterns. | 
| Concatenation operator | Combines multiple values into one. | 
| WITHexpression | Creates variables for re-use and produces a result expression. | 
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 isn't found in the struct, an error is thrown.
- For JSON:JSON. If a field isn't found in a JSON value, a SQLNULLis 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 produceNULLinstead of an error, useSAFE_OFFSET(index). This position keyword produces the same result asindexby itself.
-  SAFE_OFFSET(index): The index starts at zero. ReturnsNULLif the index is out of range.
-  ORDINAL(index): The index starts at one. Produces an error if the index is out of range. To produceNULLinstead of an error, useSAFE_ORDINAL(index).
-  SAFE_ORDINAL(index): The index starts at one. ReturnsNULLif 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 produceNULLinstead 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's 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's out of range in an array, and a positional
keyword that begins with SAFE 
isn't 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 asindexby 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's 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's 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: TheJSONexpression that contains an array element or field to return.
-  [array_element_id]: AnINT64expression 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 SQLNULLis returned.
-  [field_name]: ASTRINGexpression that represents the name of a field in JSON. If the field name isn't found, or the JSON expression isn't a JSON object, a SQLNULLis returned.
Return type
 JSON 
Example
In the following example:
-  json_valueis a JSON expression.
-  .classis a JSON field access.
-  .studentsis 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 orBYTESY: Same type asX | Takes two bit patterns of equal length and performs the logical inclusive ORoperation on each pair of the corresponding bits.
This operator throws an error ifXandYare bytes of
different lengths. | 
|   
Bitwise xor | X ^ Y | X: Integer orBYTESY: Same type asX | Takes two bit patterns of equal length and performs the
logical exclusive ORoperation on each pair of the corresponding
bits.
This operator throws an error ifXandYare bytes of
different lengths. | 
|   
Bitwise and | X & Y | X: Integer orBYTESY: Same type asX | Takes two bit patterns of equal length and performs the
logical ANDoperation on each pair of the corresponding bits.
This operator throws an error ifXandYare bytes of
different lengths. | 
|   
Left shift | X << Y | X: Integer orBYTESY:INT64 | Shifts the first operand Xto the left.
This operator returns0or a byte sequence ofb'\x00'if the second operandYis greater than or equal to
the bit length of the first operandX(for example,64ifXhas the typeINT64).
This operator throws an error ifYis negative. | 
|   
Right shift | X >> Y | X: Integer orBYTESY:INT64 | Shifts the first operand Xto the right. This operator doesn't
perform sign bit extension with a signed type (i.e., it fills vacant bits on the left
with0). This operator returns0or a byte sequence ofb'\x00'if the second operandYis greater than or equal to
the bit length of the first operandX(for example,64ifXhas the typeINT64).
This operator throws an error ifYis 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 | 
The order of evaluation of operands to AND 
and OR 
can vary, and evaluation
can be skipped if unnecessary.
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 TRUEifXis less thanY.
        
This operator supports specifying collation 
. | 
|   
Less Than or Equal To | X <= Y | Returns TRUEifXis less than or equal toY.
        
This operator supports specifying collation 
. | 
|   
Greater Than | X > Y | Returns TRUEifXis greater thanY.
        
This operator supports specifying collation 
. | 
|   
Greater Than or Equal To | X >= Y | Returns TRUEifXis greater than or equal toY.
        
This operator supports specifying collation 
. | 
|   
Equal | X = Y | Returns TRUEifXis equal toY.
        
This operator supports specifying collation 
. | 
|   
Not Equal | X != YX <> Y | Returns TRUEifXisn't equal toY.
        
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's 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 withNaNreturnFALSE, except for!=and<>, which returnTRUE.
-  BOOL:FALSEis 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, seeJSONfunctions .
-  NULL: Any operation with aNULLinput returnsNULL.
-  STRUCT: When testing a struct for equality, it's possible that one or more fields areNULL. In such cases:- If all non- NULLfield values are equal, the comparison returnsNULL.
- If any non- NULLfield values aren't equal, the comparison returnsFALSE.
 The following table demonstrates how STRUCTdata types are compared when they have fields that areNULLvalued.Struct1 Struct2 Struct1 = Struct2 STRUCT(1, NULL)STRUCT(1, NULL)NULLSTRUCT(1, NULL)STRUCT(2, NULL)FALSESTRUCT(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's 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 UNNESTdoesn't 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 FALSEifvalue_setis empty.
- Returns NULLifsearch_valueisNULL.
- Returns TRUEifvalue_setcontains a value equal tosearch_value.
- Returns NULLifvalue_setcontains aNULL.
- Returns FALSE.
When using the NOT IN 
operator, the following semantics apply in this order:
- Returns TRUEifvalue_setis empty.
- Returns NULLifsearch_valueisNULL.
- Returns FALSEifvalue_setcontains a value equal tosearch_value.
- Returns NULLifvalue_setcontains 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 TRUEifXevaluates toTRUE.
        Otherwise, evaluates toFALSE. | 
| X IS NOT TRUE | BOOL | BOOL | Evaluates to FALSEifXevaluates toTRUE.
        Otherwise, evaluates toTRUE. | 
| X IS FALSE | BOOL | BOOL | Evaluates to TRUEifXevaluates toFALSE.
        Otherwise, evaluates toFALSE. | 
| X IS NOT FALSE | BOOL | BOOL | Evaluates to FALSEifXevaluates toFALSE.
        Otherwise, evaluates toTRUE. | 
| X IS NULL | Any value type | BOOL | Evaluates to TRUEifXevaluates toNULL.
        Otherwise evaluates toFALSE. | 
| X IS NOT NULL | Any value type | BOOL | Evaluates to FALSEifXevaluates toNULL.
        Otherwise evaluates toTRUE. | 
| X IS UNKNOWN | BOOL | BOOL | Evaluates to TRUEifXevaluates toNULL.
        Otherwise evaluates toFALSE. | 
| X IS NOT UNKNOWN | BOOL | BOOL | Evaluates to FALSEifXevaluates toNULL.
        Otherwise, evaluates toTRUE. | 
 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]) xreturning2.
-  SELECT * FROM UNNEST([a,b]) x GROUP BY xreturning 2 rows.
 a IS DISTINCT FROM b 
is equivalent to NOT (a = b) 
, except for the
following cases:
- This operator never returns NULLsoNULLvalues are considered to be distinct from non-NULLvalues, not otherNULLvalues.
-  NaNvalues are considered to be distinct from non-NaNvalues, but not otherNaNvalues.
You can use this operation with fields in a complex data type, but not on the complex data types themselves. These complex data types can't be compared directly:
-  STRUCT
-  ARRAY
Input values:
-  expression_1: The first value to compare. This can be a groupable data type,NULLorNaN.
-  expression_2: The second value to compare. This can be a groupable data type,NULLorNaN.
-  NOT: If present, the outputBOOLvalue 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 
doesn't 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_2represents an arbitrary string specifier . An arbitrary string specifier can represent any sequence of0or 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 isn'tund:ci.
 
-  
-  These additional rules apply to the underscore ( _) character:-  If the collator isn't und:ci, an error is produced when an underscore isn't escaped inexpression_2.
-  If the collator isn't und:ci, the underscore isn't 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:cicollator doesn't fully normalize a string. Some canonically equivalent strings are considered unequal for both the=andLIKEoperators.
-  The LIKEoperator 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
 \u1E9Eand\U00DFare considered equal but differ in tertiary. They are considered equal withund:cicollation 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
isn't found, or otherwise NULL 
. NOT LIKE 
returns FALSE 
if a
matching pattern is found, TRUE 
if a matching pattern isn't found, or
otherwise NULL 
.
-  search_value: The value to search for matching patterns. This value can be aSTRINGorBYTEStype.
-  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_valuetype.
-  pattern_array: AnUNNESToperation that returns a column of values with the same type assearch_valuefrom an array expression.
 The regular expressions that are supported by the LIKEoperator are also supported bypatternsin the quantifiedLIKEoperator .
-  
-  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  LIKEoperator also apply to the quantifiedLIKEoperator.
- 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 FALSEifpatternsis empty.
- Returns NULLifsearch_valueisNULL.
- Returns TRUEifsearch_valuematches at least one value inpatterns.
- Returns NULLif a pattern inpatternsisNULLand other patterns inpatternsdon't match.
- Returns FALSE.
When using the quantified LIKE 
operator with ALL 
, the following semantics
apply in this order:
- For pattern_array, returnsFALSEifpatternsis empty.
- Returns NULLifsearch_valueisNULL.
- Returns TRUEifsearch_valuematches all values inpatterns.
- Returns NULLif a pattern inpatternsisNULLand other patterns inpatternsdon'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, returnsTRUEifpatternsis empty.
- Returns NULLifsearch_valueisNULL.
- Returns TRUEifsearch_valuedoesn't match at least one value inpatterns.
- Returns NULLif a pattern inpatternsisNULLand other patterns inpatternsdon't match.
- Returns FALSE.
When using the quantified NOT LIKE 
operator with ALL 
, the following
semantics apply in this order:
- For pattern_array, returnsTRUEifpatternsis empty.
- Returns NULLifsearch_valueisNULL.
- Returns TRUEifsearch_valuematches none of the values inpatterns.
- Returns NULLif a pattern inpatternsisNULLand other patterns inpatternsdon't match.
- Returns FALSE.
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
isn't 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> | 
 WITH 
expression
 
   WITH 
 ( 
 variable_assignment 
 [ 
 , 
  
 ... 
 ] 
 , 
  
 result_expression 
 ) 
 variable_assignment 
 : 
  
 variable_name 
  
 AS 
  
 expression 
 
 
Description
Creates one or more variables. Each variable can be used in subsequent
expressions within the WITH 
expression. Returns the value of result_expression 
.
-  variable_assignment: Introduces a variable. The variable name must be unique within a givenWITHexpression. Each expression can reference the variables that come before it. For example, if you create variablea, then follow it with variableb, then you can referenceainside of the expression forb.-  variable_name: The name of the variable.
-  expression: The value to assign to the variable.
 
-  
-  result_expression: An expression that can use all of the variables defined before it. The value ofresult_expressionis returned by theWITHexpression.
Return Type
- The type of the result_expression.
Requirements and Caveats
- A variable can only be assigned once within a WITHexpression.
- Variables created during WITHmay not be used in analytic or aggregate function arguments. For example,WITH(a AS ..., SUM(a))produces an error.
- Each variable's expression is evaluated only once.
Examples
The following example first concatenates variable a 
with b 
, then variable b 
with c 
:
  SELECT 
  
 WITH 
 ( 
 a 
  
 AS 
  
 '123' 
 , 
  
 -- a is '123' 
  
 b 
  
 AS 
  
 CONCAT 
 ( 
 a 
 , 
  
 '456' 
 ), 
  
 -- b is '123456' 
  
 c 
  
 AS 
  
 '789' 
 , 
  
 -- c is '789' 
  
 CONCAT 
 ( 
 b 
 , 
  
 c 
 )) 
  
 AS 
  
 result 
 ; 
  
 -- b + c is '123456789' 
 /*-------------* 
 | result      | 
 +-------------+ 
 | '123456789' | 
 *-------------*/ 
 
 
In the following example, the volatile expression RAND() 
is evaluated once.
The value of the result expression is always 0.0 
:
  SELECT 
  
 WITH 
 ( 
 a 
  
 AS 
  
 RAND 
 (), 
  
 a 
  
 - 
  
 a 
 ); 
 /*---------* 
 | result  | 
 +---------+ 
 | 0.0     | 
 *---------*/ 
 
 
Aggregate or analytic function results can be stored in variables.
  SELECT 
  
 WITH 
 ( 
 s 
  
 AS 
  
 SUM 
 ( 
 input 
 ), 
  
 c 
  
 AS 
  
 COUNT 
 ( 
 input 
 ), 
  
 s 
 / 
 c 
 ) 
 FROM 
  
 UNNEST 
 ( 
 [ 
 1.0 
 , 
  
 2.0 
 , 
  
 3.0 
 ] 
 ) 
  
 AS 
  
 input 
 ; 
 /*---------* 
 | result  | 
 +---------+ 
 | 2.0     | 
 *---------*/ 
 
 
Variables can't be used in aggregate or analytic function call arguments.
  SELECT 
  
 WITH 
 ( 
 diff 
  
 AS 
  
 a 
  
 - 
  
 b 
 , 
  
 AVG 
 ( 
 diff 
 )) 
 FROM 
  
 UNNEST 
 ( 
 [ 
  
 STRUCT 
 ( 
 1 
  
 AS 
  
 a 
 , 
  
 2 
  
 AS 
  
 b 
 ), 
  
 STRUCT 
 ( 
 3 
  
 AS 
  
 a 
 , 
  
 4 
  
 AS 
  
 b 
 ), 
  
 STRUCT 
 ( 
 5 
  
 AS 
  
 a 
 , 
  
 6 
  
 AS 
  
 b 
 ) 
  
 ] 
 ); 
 -- ERROR: WITH variables like 'diff' can't be used in aggregate or analytic 
 -- function arguments. 
 
 
A WITH 
expression is different from a WITH 
clause. The following example
shows a query that uses both:
  WITH 
  
 my_table 
  
 AS 
  
 ( 
  
 SELECT 
  
 1 
  
 AS 
  
 x 
 , 
  
 2 
  
 AS 
  
 y 
  
 UNION 
  
 ALL 
  
 SELECT 
  
 3 
  
 AS 
  
 x 
 , 
  
 4 
  
 AS 
  
 y 
  
 UNION 
  
 ALL 
  
 SELECT 
  
 5 
  
 AS 
  
 x 
 , 
  
 6 
  
 AS 
  
 y 
 ) 
 SELECT 
  
 WITH 
 ( 
 a 
  
 AS 
  
 SUM 
 ( 
 x 
 ), 
  
 b 
  
 AS 
  
 COUNT 
 ( 
 x 
 ), 
  
 a 
 / 
 b 
 ) 
  
 AS 
  
 avg_x 
 , 
  
 AVG 
 ( 
 y 
 ) 
  
 AS 
  
 avg_y 
 FROM 
  
 my_table 
 WHERE 
  
 x 
 > 
 1 
 ; 
 /*-------+-------+ 
 | avg_x | avg_y | 
 +-------+-------+ 
 | 4     | 5     | 
 +-------+-------*/ 
 
 

