JSON
ARRAY
OFFSET
or ORDINAL
—see Array Functions .JSON
+
-
~
BYTES
*
/
||
STRING
, BYTES
, or ARRAY<T>
+
DATE
with INT64
, INTERVAL
-
DATE
with INT64
, INTERVAL
<<
BYTES
>>
BYTES
&
BYTES
^
BYTES
|
BYTES
=
<
>
<=
>=
!=
, <>
[NOT] LIKE
STRING
and BYTES
STRING
and BYTES
[NOT] BETWEEN
[NOT] IN
IS [NOT] NULL
NULL
IS [NOT] TRUE
BOOL
TRUE
.IS [NOT] FALSE
BOOL
FALSE
.NOT
BOOL
NOT
AND
BOOL
AND
OR
BOOL
OR
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
Name | Summary |
---|---|
Field access operator | Gets the value of a field. |
Array subscript operator | Gets a value from an array at a specific position. |
Struct subscript operator | Gets the value of a field at a selected position in a struct. |
JSON subscript operator | Gets a value of an array element or field in a JSON expression. |
Arithmetic operators | Performs arithmetic operations. |
Date arithmetics operators | Performs arithmetic operations on dates. |
Datetime subtraction | Computes the difference between two datetimes as an interval. |
Interval arithmetic operators | Adds an interval to a datetime or subtracts an interval from a datetime. |
Bitwise operators | Performs bit manipulation. |
Logical operators | Tests for the truth of some condition and produces TRUE , FALSE , or NULL . |
Comparison operators | Compares operands and produces the results of the comparison as a BOOL value. |
EXISTS operator | Checks if a subquery produces one or more rows. |
IN operator | Checks for an equal value in a set of values. |
IS operators | Checks for the truth of a condition and produces either TRUE or FALSE . |
IS DISTINCT FROM operator | Checks if values are considered to be distinct from each other. |
LIKE operator | Checks if values are like or not like one another. |
Quantified LIKE operator | Checks a search value for matches against several patterns. |
Concatenation operator | Combines multiple values into one. |
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
STRUCT
: SQL data type of fieldname
. If a field isn't found in the struct, an error is thrown.JSON
: JSON
. If a field isn't found in a JSON value, a SQL NULL
is returned.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_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 produce NULL
instead of an error, use SAFE_OFFSET(index)
. This position keyword produces the same result as index
by itself.SAFE_OFFSET(index)
: The index starts at zero. Returns NULL
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 produce NULL
instead of an error, use SAFE_ORDINAL(index)
.SAFE_ORDINAL(index)
: The index starts at one. Returns NULL
if the index is out of range.index
: An integer that represents a specific position in the array. If used by itself without a position keyword, the index starts at zero and produces an error if the index is out of range. To produce NULL
instead of an error, use the SAFE_OFFSET(index)
or SAFE_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"]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 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]ASitem_offset
-- Error. Array index 6 is out of bounds.SELECT["coffee","tea","milk"][OFFSET(6)]ASitem_offset
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 as index
by itself.ORDINAL(index)
: The index starts at one. Produces an error if the index is out of range.index
: An integer literal or constant that represents a specific position in the struct. If used by itself without a position keyword, the index starts at zero and produces an error if the index is out of range.Examples
In following query, the struct subscript operator is used to return values at specific locations in item_struct
using position keywords. This query also shows what happens when you reference an index (6
) in an struct that's out of range.
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 is produced. 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_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
: The JSON
expression that contains an array element or field to return.[array_element_id]
: An INT64
expression that represents a zero-based index in the array. If a negative value is entered, or the value is greater than or equal to the size of the array, or the JSON expression doesn't represent a JSON array, a SQL NULL
is returned.[field_name]
: A STRING
expression 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 SQL NULL
is returned.Return type
JSON
Example
In the following example:
json_value
is a JSON expression..class
is a JSON field access..students
is a JSON field access.[0]
is a JSON subscript expression with an element offset that accesses the zeroth element of an array in the JSON value.['name']
is a JSON subscript expression with a field name that accesses a field.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" | *-----------------*/
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 |
Operators '+' and '-' can be used for arithmetic operations on dates.
date_expression+int64_expressionint64_expression+date_expressiondate_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
SELECTDATE"2020-09-22"+1ASday_later,DATE"2020-09-22"-7ASweek_ago/*------------+------------* | day_later | week_ago | +------------+------------+ | 2020-09-23 | 2020-09-15 | *------------+------------*/
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 | *-------------------+------------------------*/
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 datetime value.
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 | *----------------+--------------+-------------+--------------*/
All bitwise operators return the same type and the same length as the first operand.
Name | Syntax | Input Data Type | Description |
---|---|---|---|
Bitwise not | ~ X | Integer or BYTES | Performs logical negation on each bit, forming the ones' complement of the given binary value. |
Bitwise or | X | Y | X : Integer or BYTES Y : Same type as X | Takes two bit patterns of equal length and performs the logical inclusive OR operation on each pair of the corresponding bits. This operator throws an error if X and Y are bytes of different lengths. |
Bitwise xor | X ^ Y | X : Integer or BYTES Y : Same type as X | Takes two bit patterns of equal length and performs the logical exclusive OR operation on each pair of the corresponding bits. This operator throws an error if X and Y are bytes of different lengths. |
Bitwise and | X & Y | X : Integer or BYTES Y : Same type as X | Takes two bit patterns of equal length and performs the logical AND operation on each pair of the corresponding bits. This operator throws an error if X and Y are bytes of different lengths. |
Left shift | X << Y | X : Integer or BYTES Y : INT64 | Shifts the first operand X to the left. This operator returns 0 or a byte sequence of b'\x00' if the second operand Y is greater than or equal to the bit length of the first operand X (for example, 64 if X has the type INT64 ). This operator throws an error if Y is negative. |
Right shift | X >> Y | X : Integer or BYTES Y : INT64 | Shifts the first operand X to the right. This operator doesn't perform sign bit extension with a signed type (i.e., it fills vacant bits on the left with 0 ). This operator returns 0 or a byte sequence of b'\x00' if the second operand Y is greater than or equal to the bit length of the first operand X (for example, 64 if X has the type INT64 ). This operator throws an error if Y is negative. |
GoogleSQL supports the AND
, OR
, and NOT
logical operators. Logical operators allow only BOOL
or NULL
input and use three-valued logic to produce a result. The result can be TRUE
, FALSE
, or NULL
:
x | y | x AND y | x OR y |
---|---|---|---|
TRUE | TRUE | TRUE | TRUE |
TRUE | FALSE | FALSE | TRUE |
TRUE | NULL | NULL | TRUE |
FALSE | TRUE | FALSE | TRUE |
FALSE | FALSE | FALSE | FALSE |
FALSE | NULL | FALSE | NULL |
NULL | TRUE | NULL | TRUE |
NULL | FALSE | FALSE | NULL |
NULL | NULL | NULL | NULL |
x | NOT x |
---|---|
TRUE | FALSE |
FALSE | TRUE |
NULL | NULL |
Examples
The examples in this section reference a table called entry_table
:
/*-------* | entry | +-------+ | a | | b | | c | | NULL | *-------*/
SELECT'a'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 | *-------*/
Compares operands and produces the results of the comparison as a BOOL
value. These comparison operators are available:
Name | Syntax | Description |
---|---|---|
Less Than | X < Y | Returns TRUE if X is less than Y . This operator supports specifying collation. |
Less Than or Equal To | X <= Y | Returns TRUE if X is less than or equal to Y . This operator supports specifying collation. |
Greater Than | X > Y | Returns TRUE if X is greater than Y . This operator supports specifying collation. |
Greater Than or Equal To | X >= Y | Returns TRUE if X is greater than or equal to Y . This operator supports specifying collation. |
Equal | X = Y | Returns TRUE if X is equal to Y . This operator supports specifying collation. |
Not Equal | X != Y X <> Y | Returns TRUE if X isn't equal to Y . This operator supports specifying collation. |
BETWEEN | X [NOT] BETWEEN Y AND Z | Returns |
LIKE | X [NOT] LIKE Y | See the `LIKE` operator for details. |
IN | Multiple | See the `IN` operator for details. |
The following rules apply to operands in a comparison operator:
=
), not equal (!=
and <>
), and IN
.The following rules apply when comparing these data types:
FLOAT64
: All comparisons with NaN
return FALSE
, except for !=
and <>
, which return TRUE
.BOOL
: FALSE
is less than TRUE
.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, see JSON
functions.NULL
: Any operation with a NULL
input returns NULL
.STRUCT
: When testing a struct for equality, it's possible that one or more fields are NULL
. In such cases:
NULL
field values are equal, the comparison returns NULL
.NULL
field values aren't equal, the comparison returns FALSE
.The following table demonstrates how STRUCT
data types are compared when they have fields that are NULL
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 |
EXISTS
operatorEXISTS(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
:
WITHWordsAS(SELECT'Intend'asvalue,'east'asdirectionUNIONALLSELECT'Secure','north'UNIONALLSELECT'Clarity','west')SELECTEXISTS(SELECTvalueFROMWordsWHEREdirection='south')asresult;/*--------* | result | +--------+ | FALSE | *--------*/
IN
operatorThe IN
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
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(SELECTelementFROMUNNEST(array_expression)ASelement)
This operator supports collation, but these limitations apply:
[NOT] IN UNNEST
doesn't support collation.Semantic rules
When using the IN
operator, the following semantics apply in this order:
FALSE
if value_set
is empty.NULL
if search_value
is NULL
.TRUE
if value_set
contains a value equal to search_value
.NULL
if value_set
contains a NULL
.FALSE
.When using the NOT IN
operator, the following semantics apply in this order:
TRUE
if value_set
is empty.NULL
if search_value
is NULL
.FALSE
if value_set
contains a value equal to search_value
.NULL
if value_set
contains a NULL
.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...)
The UNNEST
form treats an array scan like UNNEST
in the FROM
clause:
x[NOT]INUNNEST(<arrayexpression>)
This form is often used with array parameters. For example:
xINUNNEST(@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)FROMtable)
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:
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 with IN
and an expression:
SELECT*FROMWordsWHEREvalueIN('Intend','Secure');/*----------* | value | +----------+ | Intend | | Secure | | Intend | *----------*/
Example with NOT IN
and an expression:
SELECT*FROMWordsWHEREvalueNOTIN('Intend');/*----------* | value | +----------+ | Secure | | Clarity | | Peace | *----------*/
Example with IN
, a scalar subquery, and an expression:
SELECT*FROMWordsWHEREvalueIN((SELECT'Intend'),'Clarity');/*----------* | value | +----------+ | Intend | | Clarity | | Intend | *----------*/
Example with IN
and an UNNEST
operation:
SELECT*FROMWordsWHEREvalueINUNNEST(['Secure','Clarity']);/*----------* | value | +----------+ | Secure | | Clarity | *----------*/
Example with IN
and a struct:
SELECT(SELECTASSTRUCTItems.info)asitemFROMItemsWHERE(info.shape,info.color)IN(('round','blue'));/*------------------------------------* | item | +------------------------------------+ | { {blue color, round shape} info } | *------------------------------------*/
IS
operatorsIS operators return TRUE or FALSE for the condition they are testing. They never return NULL
, even for NULL
inputs, unlike the IS_INF
and IS_NAN
functions defined in Mathematical Functions. If NOT
is present, the output BOOL
value is inverted.
Function Syntax | Input Data Type | Result Data Type | Description |
---|---|---|---|
X IS TRUE | BOOL | BOOL | Evaluates to TRUE if X evaluates to TRUE . Otherwise, evaluates to FALSE . |
X IS NOT TRUE | BOOL | BOOL | Evaluates to FALSE if X evaluates to TRUE . Otherwise, evaluates to TRUE . |
X IS FALSE | BOOL | BOOL | Evaluates to TRUE if X evaluates to FALSE . Otherwise, evaluates to FALSE . |
X IS NOT FALSE | BOOL | BOOL | Evaluates to FALSE if X evaluates to FALSE . Otherwise, evaluates to TRUE . |
X IS NULL | Any value type | BOOL | Evaluates to TRUE if X evaluates to NULL . Otherwise evaluates to FALSE . |
X IS NOT NULL | Any value type | BOOL | Evaluates to FALSE if X evaluates to NULL . Otherwise evaluates to TRUE . |
X IS UNKNOWN | BOOL | BOOL | Evaluates to TRUE if X evaluates to NULL . Otherwise evaluates to FALSE . |
X IS NOT UNKNOWN | BOOL | BOOL | Evaluates to FALSE if X evaluates to NULL . Otherwise, evaluates to TRUE . |
IS DISTINCT FROM
operatorexpression_1IS[NOT]DISTINCTFROMexpression_2
Description
IS DISTINCT FROM
returns TRUE
if the input values are considered to be distinct from each other by the DISTINCT
and GROUP BY
clauses. Otherwise, returns FALSE
.
a IS DISTINCT FROM b
being TRUE
is equivalent to:
SELECT COUNT(DISTINCT x) FROM UNNEST([a,b]) x
returning 2
.SELECT * FROM UNNEST([a,b]) x GROUP BY x
returning 2 rows.a IS DISTINCT FROM b
is equivalent to NOT (a = b)
, except for the following cases:
NULL
so NULL
values are considered to be distinct from non-NULL
values, not other NULL
values.NaN
values are considered to be distinct from non-NaN
values, but not other NaN
values.You can use this operation with fields in a complex data type, but not on the complex data types themselves. These complex data types can't be compared directly:
STRUCT
ARRAY
Input values:
expression_1
: The first value to compare. This can be a groupable data type, NULL
or NaN
.expression_2
: The second value to compare. This can be a groupable data type, NULL
or NaN
.NOT
: If present, the output BOOL
value is inverted.Return type
BOOL
Examples
These return TRUE
:
SELECT1ISDISTINCTFROM2
SELECT1ISDISTINCTFROMNULL
SELECT1ISNOTDISTINCTFROM1
SELECTNULLISNOTDISTINCTFROMNULL
These return FALSE
:
SELECTNULLISDISTINCTFROMNULL
SELECT1ISDISTINCTFROM1
SELECT1ISNOTDISTINCTFROM2
SELECT1ISNOTDISTINCTFROMNULL
LIKE
operatorexpression_1[NOT]LIKEexpression_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:
%
) matches any number of characters or bytes._
) matches a single character or byte.\
, _
, 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:
%
character in expression_2
represents an arbitrary string specifier. An arbitrary string specifier can represent any sequence of 0
or more characters.A character in the expression represents itself and is considered a single character specifier unless:
The character is a percent sign (%
).
The character is an underscore (_
) and the collator isn't und: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 in expression_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:ci
collator doesn't fully normalize a string. Some canonically equivalent strings are considered unequal for both the =
and LIKE
operators.
The LIKE
operator with collation has the same behavior as the =
operator when there are no wildcards in the strings.
Character sequences with secondary or higher-weighted differences are considered unequal. This includes accent differences and some special cases.
For example there are three ways to produce German sharp ß
:
\u1E9E
\U00DF
ss
\u1E9E
and \U00DF
are considered equal but differ in tertiary. They are considered equal with und:ci
collation but different from ss
, 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 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 array to find a match with the LIKE
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 the LIKE
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 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 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 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 TRUECOLLATE('\u3042','und:ci')LIKECOLLATE('%\u30A2%','und:ci');
-- Returns TRUECOLLATE('\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 TRUECOLLATE('\u0061\u030A','und:ci')LIKE'%\u00C5%';
-- Returns TRUECOLLATE('\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 TRUECOLLATE('\u0083','und:ci')LIKE'';
LIKE
operatorThe quantified LIKE
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
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 a STRING
or BYTES
type.patterns
: The patterns to look for in the search value. Each pattern must resolve to the same type as search_value
.
pattern_expression_list
: A list of one or more patterns that match the search_value
type.
pattern_array
: An UNNEST
operation that returns a column of values with the same type as search_value
from an array expression.
The regular expressions that are supported by the LIKE
operator are also supported by patterns
in the quantified LIKE
operator.
quantifier
: Condition for pattern matching.
ANY
: Checks if the set of patterns contains at least one pattern that matches the search value.
SOME
: Synonym for ANY
.
ALL
: Checks if every pattern in the set of patterns matches the search value.
Collation caveats
Collation is supported, but with the following caveats:
LIKE
operator also apply to the quantified LIKE
operator.Semantics rules
When using the quantified LIKE
operator with ANY
or SOME
, the following semantics apply in this order:
FALSE
if patterns
is empty.NULL
if search_value
is NULL
.TRUE
if search_value
matches at least one value in patterns
.NULL
if a pattern in patterns
is NULL
and other patterns in patterns
don't match.FALSE
.When using the quantified LIKE
operator with ALL
, the following semantics apply in this order:
pattern_array
, returns FALSE
if patterns
is empty.NULL
if search_value
is NULL
.TRUE
if search_value
matches all values in patterns
.NULL
if a pattern in patterns
is NULL
and other patterns in patterns
don't match.FALSE
.When using the quantified NOT LIKE
operator with ANY
or SOME
, the following semantics apply in this order:
pattern_array
, returns TRUE
if patterns
is empty.NULL
if search_value
is NULL
.TRUE
if search_value
doesn't match at least one value in patterns
.NULL
if a pattern in patterns
is NULL
and other patterns in patterns
don't match.FALSE
.When using the quantified NOT LIKE
operator with ALL
, the following semantics apply in this order:
pattern_array
, returns TRUE
if patterns
is empty.NULL
if search_value
is NULL
.TRUE
if search_value
matches none of the values in patterns
.NULL
if a pattern in patterns
is NULL
and other patterns in patterns
don't match.FALSE
.Details
Some computation limitations apply. For more information, see Quotas and limits.
Return Data Type
BOOL
Examples
The following example checks to see if the Intend%
or %intention%
pattern exists in a value and produces that value if either pattern is found:
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 with LIKE 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 pattern isn'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 for patterns
. 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 the quantified LIKE
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 the quantified LIKE
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');
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> |
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-04-17 UTC.