Operators Stay organized with collections Save and categorize content based on your preferences.
GoogleSQL for BigQuery supports operators.Operators are represented by special characters or keywords; they don't usefunction call syntax. An operator manipulates any number of data inputs, alsocalled operands, and returns a result.
Common conventions:
- Unless otherwise specified, all operators return
NULL
when one of theoperands isNULL
. - All operators will throw an error if the computation result overflows.
- For all floating point operations,
+/-inf
andNaN
may only be returnedif one of the operands is+/-inf
orNaN
. In other cases, an error isreturned.
Operator precedence
The following table lists all GoogleSQL operators from highest tolowest precedence, i.e., the order in which they will be evaluated within astatement.
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 withOFFSET orORDINAL —seeArray 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 orBYTES | 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,DATE withINT64 ,INTERVAL | Addition | Binary |
- | All numeric types,DATE withINT64 ,INTERVAL | Subtraction | Binary | |
5 | << | Integer orBYTES | Bitwise left-shift | Binary |
>> | Integer orBYTES | Bitwise right-shift | Binary | |
6 | & | Integer orBYTES | Bitwise and | Binary |
7 | ^ | Integer orBYTES | Bitwise xor | Binary |
8 | | | Integer orBYTES | Bitwise or | Binary |
9 (Comparison Operators) | = | Any comparable type. SeeData Types for a complete list. | Equal | Binary |
< | Any comparable type. SeeData Types for a complete list. | Less than | Binary | |
> | Any comparable type. SeeData Types for a complete list. | Greater than | Binary | |
<= | Any comparable type. SeeData Types for a complete list. | Less than or equal to | Binary | |
>= | Any comparable type. SeeData Types for a complete list. | Greater than or equal to | Binary | |
!= ,<> | Any comparable type. SeeData Types for a complete list. | Not equal | Binary | |
[NOT] LIKE | STRING andBYTES | Value does [not] match the pattern specified | Binary | |
Quantified LIKE | STRING andBYTES | Checks a search value for matches against several patterns. | Binary | |
[NOT] BETWEEN | Any comparable types. SeeData Types for a complete list. | Value is [not] within the range specified | Binary | |
[NOT] IN | Any comparable types. SeeData 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 | LogicalNOT | Unary |
11 | AND | BOOL | LogicalAND | Binary |
12 | OR | BOOL | LogicalOR | 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 thoseoperators are grouped together starting from the left and moving right. Forexample, 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 operatorsaren't associative. Therefore, parentheses are required to resolveambiguity. 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 producesTRUE ,FALSE , orNULL . |
Comparison operators | Compares operands and produces the results of the comparison as aBOOL 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 eitherTRUE orFALSE . |
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. |
QuantifiedLIKE operator | Checks a search value for matches against several patterns. |
Concatenation operator | Combines multiple values into one. |
WITH expression | 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 beused to access nested fields. For example,expression.fieldname1.fieldname2
.
Input values:
STRUCT
JSON
STRUCT
, you can use thestruct subscript operator to access the field byits position within theSTRUCT
instead of by its name. Accessing bya field by position is useful when fields are un-named or have ambiguous names.Return type
- For
STRUCT
: SQL data type offieldname
. If a field isn't found inthe struct, an error is thrown. - For
JSON
:JSON
. If a field isn't found in a JSON value, a SQLNULL
isreturned.
Example
In the following example, the field access operations are.address
and.country
.
SELECTSTRUCT(STRUCT('Yonge Street'ASstreet,'Canada'AScountry)ASaddress).address.country/*---------* | country | +---------+ | Canada | *---------*/
Array subscript operator
Note: Syntax wrapped in double quotes (""
) is required.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 shouldstart and how out-of-range indexes are handled. The index is an integer thatrepresents a specific position in the array.OFFSET(index)
: The index starts at zero. Produces an error if the index isout of range. To produceNULL
instead of an error, useSAFE_OFFSET(index)
. Thisposition keyword produces the same result asindex
by itself.SAFE_OFFSET(index)
: The index starts atzero. 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 atone. ReturnsNULL
if the index is out of range.
index
: An integer that represents a specific position in the array. If usedby itself without a position keyword, the index starts at zero and producesan 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
wherearray_expression
isARRAY<T>
.
Examples
In following query, the array subscript operator is used to return values atspecific position initem_array
. This query also shows what happens when youreference an index (6
) in an array that's out of range. If theSAFE
prefixis included,NULL
is returned, otherwise an error is produced.
SELECT["coffee","tea","milk"]ASitem_array,["coffee","tea","milk"][0]ASitem_index,["coffee","tea","milk"][OFFSET(0)]ASitem_offset,["coffee","tea","milk"][ORDINAL(1)]ASitem_ordinal,["coffee","tea","milk"][SAFE_OFFSET(6)]ASitem_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 positionalkeyword that begins withSAFE
isn't included, an error is produced.For example:
-- Error. Array index 6 is out of bounds.SELECT["coffee","tea","milk"][6]ASitem_offset
-- Error. Array index 6 is out of bounds.SELECT["coffee","tea","milk"][OFFSET(6)]ASitem_offset
Struct subscript operator
Note: Syntax wrapped in double quotes (""
) is required.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 shouldstart and how out-of-range indexes are handled. The index is aninteger literal or constant that represents a specific position in the struct.OFFSET(index)
: The index starts at zero. Produces an error if the index isout of range. Produces the sameresult asindex
by itself.ORDINAL(index)
: The index starts at one. Produces an error if the indexis out of range.
index
: An integer literal or constant that represents a specific position inthe struct. If used by itself without a position keyword, the index starts atzero and produces an error if the index is out of range.
SAFE
positional keywordsat this time.Examples
In following query, the struct subscript operator is used to return values atspecific locations initem_struct
using position keywords. This query alsoshows what happens when you reference an index (6
) in an struct that's out ofrange.
SELECTSTRUCT<INT64,STRING,BOOL>(23,"tea",FALSE)[0]ASfield_index,STRUCT<INT64,STRING,BOOL>(23,"tea",FALSE)[OFFSET(0)]ASfield_offset,STRUCT<INT64,STRING,BOOL>(23,"tea",FALSE)[ORDINAL(1)]ASfield_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 isproduced. For example:
-- Error: Field ordinal 6 is out of bounds in STRUCTSELECTSTRUCT<INT64,STRING,BOOL>(23,"tea",FALSE)[6]ASfield_offset
-- Error: Field ordinal 6 is out of bounds in STRUCTSELECTSTRUCT<INT64,STRING,BOOL>(23,"tea",FALSE)[OFFSET(6)]ASfield_offset
JSON subscript operator
Note: Syntax wrapped in double quotes (""
) is required.json_expression"["array_element_id"]"
json_expression"["field_name"]"
Description
Gets a value of an array element or field in a JSON expression. Can beused to access nested data.
Input values:
JSON expression
: TheJSON
expression that contains an array element orfield to return.[array_element_id]
: AnINT64
expression that represents a zero-based indexin the array. If a negative value is entered, or the value is greater thanor equal to the size of the array, or the JSON expression doesn't representa JSON array, a SQLNULL
is returned.[field_name]
: ASTRING
expression that represents the name of a field inJSON. If the field name isn't found, or the JSON expression isn't aJSON 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 thataccesses the zeroth element of an array in the JSON value.['name']
is a JSON subscript expression with a field name thataccesses a field.
SELECTjson_value.class.students[0]['name']ASfirst_studentFROMUNNEST([JSON'{"class" : {"students" : [{"name" : "Jane"}]}}',JSON'{"class" : {"students" : []}}',JSON'{"class" : {"students" : [{"name" : "John"}, {"name": "Jamie"}]}}'])ASjson_value;/*-----------------* | first_student | +-----------------+ | "Jane" | | NULL | | "John" | *-----------------*/
Arithmetic operators
All arithmetic operators accept input of numeric typeT
, and the result typehas typeT
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 theIEEE_DIVIDE
orSAFE_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_expressionint64_expression+date_expressiondate_expression-int64_expression
Description
Adds or subtractsint64_expression
days to or fromdate_expression
. This isequivalent toDATE_ADD
orDATE_SUB
functions, when interval is expressed indays.
Return Data Type
DATE
Example
SELECTDATE"2020-09-22"+1ASday_later,DATE"2020-09-22"-7ASweek_ago/*------------+------------* | day_later | week_ago | +------------+------------+ | 2020-09-23 | 2020-09-15 | *------------+------------*/
Datetime subtraction
date_expression-date_expressiontimestamp_expression-timestamp_expressiondatetime_expression-datetime_expression
Description
Computes the difference between two datetime values as an interval.
Return Data Type
INTERVAL
Example
SELECTDATE"2021-05-20"-DATE"2020-04-19"ASdate_diff,TIMESTAMP"2021-06-01 12:34:56.789"-TIMESTAMP"2021-05-31 00:00:00"AStime_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=DATETIMEdate_expression-interval_expression=DATETIMEtimestamp_expression+interval_expression=TIMESTAMPtimestamp_expression-interval_expression=TIMESTAMPdatetime_expression+interval_expression=DATETIMEdatetime_expression-interval_expression=DATETIME
Description
Adds an interval to a datetime value or subtracts an interval from a datetimevalue.
Example
SELECTDATE"2021-04-20"+INTERVAL25HOURASdate_plus,TIMESTAMP"2021-05-02 00:01:02.345"-INTERVAL10SECOND AStime_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=INTERVALinterval_expression/integer_expression=INTERVAL
Description
Multiplies or divides an interval value by an integer.
Example
SELECTINTERVAL'1:2:3'HOURTOSECOND*10ASmul1,INTERVAL35SECOND*4ASmul2,INTERVAL10YEAR/3ASdiv1,INTERVAL1MONTH/12ASdiv2/*----------------+--------------+-------------+--------------* | 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 asthe first operand.
Name | Syntax | Input Data Type | Description |
---|---|---|---|
Bitwise not | ~ X | Integer orBYTES | Performs logical negation on each bit, forming the ones' complement of thegiven binary value. |
Bitwise or | X | Y | X : Integer orBYTES Y : Same type asX | Takes two bit patterns of equal length and performs the logical inclusiveOR operation on each pair of the corresponding bits.This operator throws an error ifX andY are bytes ofdifferent lengths. |
Bitwise xor | X ^ Y | X : Integer orBYTES Y : Same type asX | Takes two bit patterns of equal length and performs thelogical exclusiveOR operation on each pair of the correspondingbits.This operator throws an error ifX andY are bytes ofdifferent lengths. |
Bitwise and | X & Y | X : Integer orBYTES Y : Same type asX | Takes two bit patterns of equal length and performs thelogicalAND operation on each pair of the corresponding bits.This operator throws an error ifX andY are bytes ofdifferent lengths. |
Left shift | X << Y | X : Integer orBYTES Y :INT64 | Shifts the first operandX to the left.This operator returns0 or a byte sequence ofb'\x00' if the second operandY is greater than or equal tothe bit length of the first operandX (for example,64 ifX has the typeINT64 ).This operator throws an error ifY is negative. |
Right shift | X >> Y | X : Integer orBYTES Y :INT64 | Shifts the first operandX to the right. This operator doesn'tperform sign bit extension with a signed type (i.e., it fills vacant bits on the leftwith0 ). This operator returns0 or a byte sequence ofb'\x00' if the second operandY is greater than or equal tothe bit length of the first operandX (for example,64 ifX has the typeINT64 ).This operator throws an error ifY is negative. |
Logical operators
GoogleSQL supports theAND
,OR
, andNOT
logical operators.Logical operators allow onlyBOOL
orNULL
inputand usethree-valued logicto produce a result. The result can beTRUE
,FALSE
, orNULL
:
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 toAND
andOR
can vary, and evaluationcan be skipped if unnecessary.
Examples
The examples in this section reference a table calledentry_table
:
/*-------* | entry | +-------+ | a | | b | | c | | NULL | *-------*/
SELECT'a'FROMentry_tableWHEREentry='a'-- a => 'a' = 'a' => TRUE-- b => 'b' = 'a' => FALSE-- NULL => NULL = 'a' => NULL/*-------* | entry | +-------+ | a | *-------*/
SELECTentryFROMentry_tableWHERENOT(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 | *-------*/
SELECTentryFROMentry_tableWHEREentryISNULL-- 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 aBOOL
value. These comparison operators are available:
Name | Syntax | Description |
---|---|---|
Less Than | X < Y | ReturnsTRUE ifX is less thanY . This operator supports specifyingcollation. |
Less Than or Equal To | X <= Y | ReturnsTRUE ifX is less than or equal toY . This operator supports specifyingcollation. |
Greater Than | X > Y | ReturnsTRUE ifX is greater thanY . This operator supports specifyingcollation. |
Greater Than or Equal To | X >= Y | ReturnsTRUE ifX is greater than or equal toY . This operator supports specifyingcollation. |
Equal | X = Y | ReturnsTRUE ifX is equal toY . This operator supports specifyingcollation. |
Not Equal | X != Y X <> Y | ReturnsTRUE ifX isn't equal toY . This operator supports specifyingcollation. |
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 becomparable.
- A comparison operator generally requires both operands to be of thesame type.
- If the operands are of different types, and the values of those types can beconverted 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 anon-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 withNaN
returnFALSE
,except for!=
and<>
, which returnTRUE
.BOOL
:FALSE
is less thanTRUE
.STRING
: Strings are compared codepoint-by-codepoint, which means thatcanonically equivalent strings are only guaranteed to compare as equal ifthey have been normalized first.JSON
: You can't compare JSON, but you can comparethe values inside of JSON if you convert the values toSQL 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 morefields areNULL
. In such cases:- If all non-
NULL
field values are equal, the comparison returnsNULL
. - If any non-
NULL
field values aren't equal, the comparison returnsFALSE
.
The following table demonstrates how
STRUCT
data types are compared whenthey 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
ReturnsTRUE
if the subquery produces one or more rows. ReturnsFALSE
ifthe subquery produces zero rows. Never returnsNULL
. To learn more abouthow you can use a subquery withEXISTS
,seeEXISTS
subqueries.
Examples
In this example, theEXISTS
operator returnsFALSE
because there are norows inWords
where the direction issouth
:
WITHWordsAS(SELECT'Intend'asvalue,'east'asdirectionUNIONALLSELECT'Secure','north'UNIONALLSELECT'Clarity','west')SELECTEXISTS(SELECTvalueFROMWordsWHEREdirection='south')asresult;/*--------* | result | +--------+ | FALSE | *--------*/
IN
operator
TheIN
operator supports the following syntax:
search_value[NOT]INvalue_setvalue_set:{(expression[,...])|(subquery)|UNNEST(array_expression)}
Description
Checks for an equal value in a set of values.Semantic rules apply, but in general,IN
returnsTRUE
if an equal value is found,FALSE
if an equal value is excluded, otherwiseNULL
.NOT IN
returnsFALSE
if an equal value is found,TRUE
if anequal value is excluded, otherwiseNULL
.
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)
: Asubquery that returnsa 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)
: AnUNNEST operatorthat returns a column of values from an array expression. This isequivalent to:IN(SELECTelementFROMUNNEST(array_expression)ASelement)
This operator supportscollation, but these limitations apply:
[NOT] IN UNNEST
doesn't support collation.- If collation is used with a list of expressions, there must be at least oneitem in the list.
Semantic rules
When using theIN
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 theNOT 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:
xIN(y,z,...)
are defined as equivalent to:
(x=y)OR(x=z)OR...
and the subquery and array forms are defined similarly.
xNOTIN...
is equivalent to:
NOT(xIN...)
TheUNNEST
form treats an array scan likeUNNEST
in theFROM
clause:
x[NOT]INUNNEST(<arrayexpression>)
This form is often used with array parameters. For example:
xINUNNEST(@array_parameter)
See theArrays topic for more informationon 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)FROMtable)
See theStruct Type topic for more information.
Return Data Type
BOOL
Examples
You can use theseWITH
clauses to emulate temporary tables forWords
andItems
in the following examples:
WITHWordsAS(SELECT'Intend'asvalueUNIONALLSELECT'Secure'UNIONALLSELECT'Clarity'UNIONALLSELECT'Peace'UNIONALLSELECT'Intend')SELECT*FROMWords;/*----------* | value | +----------+ | Intend | | Secure | | Clarity | | Peace | | Intend | *----------*/
WITHItemsAS(SELECTSTRUCT('blue'AScolor,'round'ASshape)ASinfoUNIONALLSELECTSTRUCT('blue','square')UNIONALLSELECTSTRUCT('red','round'))SELECT*FROMItems;/*----------------------------* | info | +----------------------------+ | {blue color, round shape} | | {blue color, square shape} | | {red color, round shape} | *----------------------------*/
Example withIN
and an expression:
SELECT*FROMWordsWHEREvalueIN('Intend','Secure');/*----------* | value | +----------+ | Intend | | Secure | | Intend | *----------*/
Example withNOT IN
and an expression:
SELECT*FROMWordsWHEREvalueNOTIN('Intend');/*----------* | value | +----------+ | Secure | | Clarity | | Peace | *----------*/
Example withIN
, a scalar subquery, and an expression:
SELECT*FROMWordsWHEREvalueIN((SELECT'Intend'),'Clarity');/*----------* | value | +----------+ | Intend | | Clarity | | Intend | *----------*/
Example withIN
and anUNNEST
operation:
SELECT*FROMWordsWHEREvalueINUNNEST(['Secure','Clarity']);/*----------* | value | +----------+ | Secure | | Clarity | *----------*/
Example withIN
and a struct:
SELECT(SELECTASSTRUCTItems.info)asitemFROMItemsWHERE(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 neverreturnNULL
, even forNULL
inputs, unlike theIS_INF
andIS_NAN
functions defined inMathematical Functions.IfNOT
is present, the outputBOOL
value isinverted.
Function Syntax | Input Data Type | Result Data Type | Description |
---|---|---|---|
X IS TRUE | BOOL | BOOL | Evaluates toTRUE ifX evaluates toTRUE . Otherwise, evaluates toFALSE . |
X IS NOT TRUE | BOOL | BOOL | Evaluates toFALSE ifX evaluates toTRUE . Otherwise, evaluates toTRUE . |
X IS FALSE | BOOL | BOOL | Evaluates toTRUE ifX evaluates toFALSE . Otherwise, evaluates toFALSE . |
X IS NOT FALSE | BOOL | BOOL | Evaluates toFALSE ifX evaluates toFALSE . Otherwise, evaluates toTRUE . |
X IS NULL | Any value type | BOOL | Evaluates toTRUE ifX evaluates toNULL . Otherwise evaluates toFALSE . |
X IS NOT NULL | Any value type | BOOL | Evaluates toFALSE ifX evaluates toNULL . Otherwise evaluates toTRUE . |
X IS UNKNOWN | BOOL | BOOL | Evaluates toTRUE ifX evaluates toNULL . Otherwise evaluates toFALSE . |
X IS NOT UNKNOWN | BOOL | BOOL | Evaluates toFALSE ifX evaluates toNULL . Otherwise, evaluates toTRUE . |
IS DISTINCT FROM
operator
expression_1IS[NOT]DISTINCTFROMexpression_2
Description
IS DISTINCT FROM
returnsTRUE
if the input values are considered to bedistinct from each other by theDISTINCT
andGROUP BY
clauses. Otherwise, returnsFALSE
.
a IS DISTINCT FROM b
beingTRUE
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 toNOT (a = b)
, except for thefollowing cases:
- This operator never returns
NULL
soNULL
values are considered to bedistinct from non-NULL
values, not otherNULL
values. NaN
values are considered to be distinct from non-NaN
values, but nototherNaN
values.
You can use this operation with fields in a complex data type, but not onthe complex data types themselves. These complex data types can't be compareddirectly:
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 groupabledata type,NULL
orNaN
.NOT
: If present, the outputBOOL
value is inverted.
Return type
BOOL
Examples
These returnTRUE
:
SELECT1ISDISTINCTFROM2
SELECT1ISDISTINCTFROMNULL
SELECT1ISNOTDISTINCTFROM1
SELECTNULLISNOTDISTINCTFROMNULL
These returnFALSE
:
SELECTNULLISDISTINCTFROMNULL
SELECT1ISDISTINCTFROM1
SELECT1ISNOTDISTINCTFROM2
SELECT1ISNOTDISTINCTFROMNULL
LIKE
operator
expression_1[NOT]LIKEexpression_2
Description
LIKE
returnsTRUE
if the string in the first operandexpression_1
matches a pattern specified by the second operandexpression_2
,otherwise returnsFALSE
.
NOT LIKE
returnsTRUE
if the string in the first operandexpression_1
doesn't match a pattern specified by the second operandexpression_2
,otherwise returnsFALSE
.
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 isrequired. For example,r'\%'
.
This operator supportscollation, but caveats apply:
- Each
%
character inexpression_2
represents anarbitrary string specifier. An arbitrary string specifier can representany sequence of0
or more characters. A character in the expression represents itself and is considered asingle 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 underscoreisn't escaped inexpression_2
.If the collator isn't
und:ci
, the underscore isn't allowed when theoperands have collation specified.Somecompatibility composites, such as the fi-ligature (
fi
) and thetelephone sign (℡
), will produce a match if they are compared to anunderscore.A single underscore matches the idea of what a character is, based onan approximation known as agrapheme cluster.
For a contiguous sequence of single character specifiers, equalitydepends on the collator and its language tags and tailoring.
By default, the
und:ci
collator doesn't fully normalize a string.Some canonically equivalent strings are considered unequal forboth 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 areconsidered unequal. This includes accent differences and somespecial 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 areconsidered equal. This includes case differences andkana subtype differences, which are considered equal.
There areignorable 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 thefirst operand matches a pattern specified by the second operand.
-- Returns TRUESELECT'apple'LIKE'a%';
-- Returns FALSESELECT'%a'LIKE'apple';
-- Returns FALSESELECT'apple'NOTLIKE'a%';
-- Returns TRUESELECT'%a'NOTLIKE'apple';
-- Produces an errorSELECTNULLLIKE'a%';
-- Produces an errorSELECT'apple'LIKENULL;
The following example illustrates how to search multiple patterns in an arrayto find a match with theLIKE
operator:
WITHWordsAS(SELECT'Intend with clarity.'asvalueUNIONALLSELECT'Secure with intention.'UNIONALLSELECT'Clarity and security.')SELECTvalueFROMWordsWHEREEXISTS(SELECTvalueFROMUNNEST(['%ity%','%and%'])ASpatternWHEREvalueLIKEpattern);/*------------------------+ | value | +------------------------+ | Intend with clarity. | | Clarity and security. | +------------------------*/
The following examples illustrate how collation can be used with theLIKE
operator.
-- Returns FALSE'Foo'LIKE'%foo%'
-- Returns TRUECOLLATE('Foo','und:ci')LIKECOLLATE('%foo%','und:ci');
-- Returns TRUECOLLATE('Foo','und:ci')=COLLATE('foo','und:ci');
-- Produces an errorCOLLATE('Foo','und:ci')LIKECOLLATE('%foo%','binary');
-- Produces an errorCOLLATE('Foo','und:ci')LIKECOLLATE('%f_o%','und:ci');
-- Returns TRUECOLLATE('Foo_','und:ci')LIKECOLLATE('%foo\\_%','und:ci');
There are two capital forms ofß
. We can use eitherSS
orẞ
as uppercase. While the difference betweenß
andẞ
is case difference (tertiarydifference), the difference between sharps
andss
is secondary andconsidered not equal using theund:ci
collator. For example:
-- Returns FALSE'MASSE'LIKE'Maße';
-- Returns FALSECOLLATE('MASSE','und:ci')LIKE'%Maße%';
-- Returns FALSECOLLATE('MASSE','und:ci')=COLLATE('Maße','und:ci');
The kana differences in Japanese are considered as tertiary or quaternarydifferences, and should be considered as equal in theund:ci
collator withsecondary strength.
'\u3042'
is'あ'
(hiragana)'\u30A2'
is'ア'
(katakana)
For example:
-- Returns FALSE'\u3042'LIKE'%\u30A2%';
-- Returns TRUECOLLATE('\u3042','und:ci')LIKECOLLATE('%\u30A2%','und:ci');
-- Returns TRUECOLLATE('\u3042','und:ci')=COLLATE('\u30A2','und:ci');
When comparing two strings, theund:ci
collator compares the collation unitsbased on the specification of the collation. Even though the number ofcode points is different, the two strings are considered equal when thecollation 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 TRUECOLLATE('\u0061\u030A','und:ci')LIKE'%\u00C5%';
-- Returns TRUECOLLATE('\u0061\u030A','und:ci')=COLLATE('\u00C5','und:ci');
In the following example,'\u0083'
is aNO BREAK HERE
character andis ignored.
-- Returns FALSE'\u0083'LIKE'';
-- Returns TRUECOLLATE('\u0083','und:ci')LIKE'';
QuantifiedLIKE
operator
The quantifiedLIKE
operator supports the following syntax:
search_value[NOT]LIKEquantifierpatternsquantifier:{ANY|SOME|ALL}patterns:{pattern_expression_list|pattern_array}pattern_expression_list:(expression[,...])pattern_array:UNNEST(array_expression)
Description
Checkssearch_value
for matches against several patterns. Each comparison iscase-sensitive. Wildcard searches are supported.Semantic rules apply, but in general,LIKE
returnsTRUE
if a matching pattern is found,FALSE
if a matching patternisn't found, or otherwiseNULL
.NOT LIKE
returnsFALSE
if amatching pattern is found,TRUE
if a matching pattern isn't found, orotherwiseNULL
.
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 mustresolve 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 withthe same type assearch_value
from an array expression.
The regular expressions that are supported by the
LIKE
operator are also supported bypatterns
in thequantifiedLIKE
operator.quantifier
: Condition for pattern matching.ANY
: Checks if the set of patterns contains at least one pattern thatmatches the search value.SOME
: Synonym forANY
.ALL
: Checks if every pattern in the set of patterns matches thesearch value.
Collation caveats
Collation is supported, but with the following caveats:
- The collation caveats that apply to the
LIKE
operator alsoapply to the quantifiedLIKE
operator. - If a collation-supported input contains no collation specification or anempty collation specification and another input contains an explicitly definedcollation, the explicitly defined collation is used for all of the inputs.
- All inputs with a non-empty, explicitly defined collation specification musthave the same type of collation specification, otherwise an error is thrown.
Semantics rules
When using the quantifiedLIKE
operator withANY
orSOME
, thefollowing 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 patternsinpatterns
don't match. - Returns
FALSE
.
When using the quantifiedLIKE
operator withALL
, the following semanticsapply 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 patternsinpatterns
don't match. - Returns
FALSE
.
When using the quantifiedNOT LIKE
operator withANY
orSOME
, thefollowing 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 patternsinpatterns
don't match. - Returns
FALSE
.
When using the quantifiedNOT LIKE
operator withALL
, the followingsemantics 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 patternsinpatterns
don't match. - Returns
FALSE
.
Return Data Type
BOOL
Examples
The following example checks to see if theIntend%
or%intention%
pattern exists in a value and produces that value if either pattern is found:
WITHWordsAS(SELECT'Intend with clarity.'asvalueUNIONALLSELECT'Secure with intention.'UNIONALLSELECT'Clarity and security.')SELECT*FROMWordsWHEREvalueLIKEANY('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 withLIKE ALL
:
WITHWordsAS(SELECT'Intend with clarity.'asvalueUNIONALLSELECT'Secure with intention.'UNIONALLSELECT'Clarity and security.')SELECT*FROMWordsWHEREvalueLIKEALL('%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 patternisn't found:
WITHWordsAS(SELECT'Intend with clarity.'asvalueUNIONALLSELECT'Secure with intention.'UNIONALLSELECT'Clarity and security.')SELECT*FROMWordsWHEREvalueNOTLIKE('%ity%');/*------------------------+ | value | +------------------------+ | Secure with intention. | +------------------------*/
You can pass in an array forpatterns
. For example:
WITHWordsAS(SELECT'Intend with clarity.'asvalueUNIONALLSELECT'Secure with intention.'UNIONALLSELECT'Clarity and security.')SELECT*FROMWordsWHEREvalueLIKEANYUNNEST(['%ion%','%and%']);/*------------------------+ | value | +------------------------+ | Secure with intention. | | Clarity and security. | +------------------------*/
The following queries illustrate some of the semantic rules for thequantifiedLIKE
operator:
SELECTNULLLIKEANY('a','b'),-- NULL'a'LIKEANY('a','c'),-- TRUE'a'LIKEANY('b','c'),-- FALSE'a'LIKEANY('a',NULL),-- TRUE'a'LIKEANY('b',NULL),-- NULLNULLNOTLIKEANY('a','b'),-- NULL'a'NOTLIKEANY('a','b'),-- TRUE'a'NOTLIKEANY('a','%a%'),-- FALSE'a'NOTLIKEANY('a',NULL),-- NULL'a'NOTLIKEANY('b',NULL);-- TRUE
SELECTNULLLIKESOME('a','b'),-- NULL'a'LIKESOME('a','c'),-- TRUE'a'LIKESOME('b','c'),-- FALSE'a'LIKESOME('a',NULL),-- TRUE'a'LIKESOME('b',NULL),-- NULLNULLNOTLIKESOME('a','b'),-- NULL'a'NOTLIKESOME('a','b'),-- TRUE'a'NOTLIKESOME('a','%a%'),-- FALSE'a'NOTLIKESOME('a',NULL),-- NULL'a'NOTLIKESOME('b',NULL);-- TRUE
SELECTNULLLIKEALL('a','b'),-- NULL'a'LIKEALL('a','%a%'),-- TRUE'a'LIKEALL('a','c'),-- FALSE'a'LIKEALL('a',NULL),-- NULL'a'LIKEALL('b',NULL),-- FALSENULLNOTLIKEALL('a','b'),-- NULL'a'NOTLIKEALL('b','c'),-- TRUE'a'NOTLIKEALL('a','c'),-- FALSE'a'NOTLIKEALL('a',NULL),-- FALSE'a'NOTLIKEALL('b',NULL);-- NULL
The following queries illustrate some of the semantic rules for thequantifiedLIKE
operator and collation:
SELECTCOLLATE('a','und:ci')LIKEALL('a','A'),-- TRUE'a'LIKEALL(COLLATE('a','und:ci'),'A'),-- TRUE'a'LIKEALL('%A%',COLLATE('a','und:ci'));-- TRUE
-- ERROR: BYTES and STRING values can't be used together.SELECTb'a'LIKEALL(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> |
CONCAT
function call. For example,'A' || 'B' || 'C'
becomesCONCAT('A', CONCAT('B', 'C'))
.WITH
expression
WITH(variable_assignment[,...],result_expression)variable_assignment:variable_nameASexpression
Description
Creates one or more variables. Each variable can be used in subsequentexpressions within theWITH
expression. Returns the value ofresult_expression
.
variable_assignment
: Introduces a variable. The variable name must beunique within a givenWITH
expression. Each expression can reference thevariables that come before it. For example, if you create variablea
,then follow it with variableb
, then you can referencea
inside of theexpression 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 definedbefore it. The value ofresult_expression
is returned by theWITH
expression.
Return Type
- The type of the
result_expression
.
Requirements and Caveats
- A variable can only be assigned once within a
WITH
expression. - Variables created during
WITH
may not be usedin analytic or aggregatefunction 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 variablea
withb
, then variableb
withc
:
SELECTWITH(aAS'123',-- a is '123'bASCONCAT(a,'456'),-- b is '123456'cAS'789',-- c is '789'CONCAT(b,c))ASresult;-- b + c is '123456789'/*-------------* | result | +-------------+ | '123456789' | *-------------*/
In the following example, the volatile expressionRAND()
is evaluated once.The value of the result expression is always0.0
:
SELECTWITH(aASRAND(),a-a);/*---------* | result | +---------+ | 0.0 | *---------*/
Aggregate or analytic functionresults can be stored in variables.
SELECTWITH(sASSUM(input),cASCOUNT(input),s/c)FROMUNNEST([1.0,2.0,3.0])ASinput;/*---------* | result | +---------+ | 2.0 | *---------*/
Variables can't be used in aggregate oranalytic function call arguments.
SELECTWITH(diffASa-b,AVG(diff))FROMUNNEST([STRUCT(1ASa,2ASb),STRUCT(3ASa,4ASb),STRUCT(5ASa,6ASb)]);-- ERROR: WITH variables like 'diff' can't be used in aggregate or analytic-- function arguments.
AWITH
expression is different from aWITH
clause. The following exampleshows a query that uses both:
WITHmy_tableAS(SELECT1ASx,2ASyUNIONALLSELECT3ASx,4ASyUNIONALLSELECT5ASx,6ASy)SELECTWITH(aASSUM(x),bASCOUNT(x),a/b)ASavg_x,AVG(y)ASavg_yFROMmy_tableWHEREx >1;/*-------+-------+ | avg_x | avg_y | +-------+-------+ | 4 | 5 | +-------+-------*/
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-10-02 UTC.