Estructura léxica y sintaxis en SQL estándar

Una instrucción de BigQuery consta de una serie de tokens. Los tokens incluyen identificadores, identificadores entrecomillados, literales, palabras clave, operadores y caracteres especiales. Puedes separar tokens con espacios en blanco (por ejemplo, espacio, retroceso, tabulación, nueva línea) o comentarios.

Identificadores

Los identificadores son nombres asociados con columnas, tablas y otros objetos de base de datos. Pueden estar entre comillas o sin ellas.

  • Los identificadores se pueden usar en expresiones de ruta que muestran una STRUCT.
  • Algunos identificadores distinguen entre mayúsculas y minúsculas y otros no. Para obtener más información, consulta Distinción entre mayúsculas y minúsculas.
  • Los identificadores sin comillas deben comenzar con una letra o un carácter de guion bajo. Los caracteres que le siguen pueden ser letras, números o guiones bajos.
  • Los identificadores entrecomillados deben estar encerrados entre caracteres de acento grave (`).
    • Los identificadores entrecomillados pueden contener cualquier carácter, como espacios o símbolos.
    • Los identificadores entrecomillados no pueden estar vacíos.
    • Los identificadores entrecomillados tienen las mismas secuencias de escape que los literales de string.
    • Una palabra clave reservada debe ser un identificador entrecomillado si es una palabra clave independiente o el primer componente de una expresión de ruta. Puede no estar entrecomillado si es el segundo componente de una expresión de ruta o un componente posterior.
  • Los identificadores de nombres de tablas tienen sintaxis adicional para admitir guiones (-) cuando se hace referencia a ellos en las cláusulas FROM y TABLE.

Ejemplos

Estos son identificadores válidos:

Customers5
`5Customers`
dataField
_dataField1
ADGROUP
`tableName~`
`GROUP`

Estas expresiones de ruta de acceso contienen identificadores válidos:

foo.`GROUP`
foo.GROUP
foo().dataField
list[OFFSET(3)].dataField
list[ORDINAL(3)].dataField
@parameter.dataField

Estos son identificadores no válidos:

5Customers
_dataField!
GROUP

5Customers comienza con un número, no con una letra o guion bajo. _dataField! contiene el carácter especial “!” que no es una letra, número o guion bajo. GROUP es una palabra clave reservada y, por lo tanto, no se puede usar como un identificador si no está encerrada entre caracteres de acento grave.

No es necesario que incluyas nombres de tabla que incluyan guiones con comillas. Estos son equivalentes:

SELECT * FROM data-customers-287.mydatabase.mytable
SELECT * FROM `data-customers-287`.mydatabase.mytable

Literales

Un literal representa un valor constante de un tipo de datos integrado. Algunos tipos de datos pueden expresarse como literales, pero no todos.

Literales de string y de bytes

Los literales de string y de bytes deben estar entre comillas simples (') o dobles ("), o entre comillas triples con grupos de tres comillas simples (''') o tres dobles (""").

Literales entrecomillados:

Literal Ejemplos Descripción
String entrecomillada
  • "abc"
  • "it's"
  • 'it\'s'
  • 'Title: "Boy"'
Las strings encerradas entre comillas simples (') pueden contener comillas dobles (") sin escapar y viceversa.
Las barras invertidas (\) ingresan secuencias de escape. Consulta la tabla Secuencias de escape a continuación.
Las strings entre comillas no pueden contener líneas nuevas, ni siquiera cuando las precede una barra invertida (\).
String entre comillas triples
  • """abc"""
  • '''it's'''
  • '''Title:"Boy"'''
  • '''two
    lines'''
  • '''why\?'''
Se permiten caracteres de línea nueva incrustados y comillas sin escapar; consulta el cuarto ejemplo.
Las barras invertidas (\) ingresan secuencias de escape. Consulta la tabla Secuencias de escape a continuación.
No se permite una barra invertida sin escape (\) al final de una línea.
Debes terminar la string con tres comillas sin escapar seguidas que coincidan con las comillas iniciales.
String sin procesar
  • R"abc+"
  • r'''abc+'''
  • R"""abc+"""
  • r'f\(abc,(.*),def\)'
Los literales con comillas o comillas triples que tienen el prefijo literal de string sin procesar (r o R) se interpretan como strings sin procesar o de expresión regular.
Los caracteres de barra invertida (\) no actúan como caracteres de escape. Si una barra invertida seguida de otro carácter aparece dentro del literal de string, se conservan ambos caracteres.
Una string sin procesar no puede terminar con un número impar de barras invertidas.
Las strings sin procesar son útiles para construir expresiones regulares.

Los caracteres de prefijo (r, R, b, B)) son opcionales para strings entre comillas o comillas triples y, además, indican que la string es una string sin procesar o de expresión regular, o bien una secuencia de bytes, respectivamente. Por ejemplo, b'abc' y b'''abc''' se interpretan como de tipo byte. Los caracteres de prefijo no distinguen entre mayúsculas y minúsculas.

Literales entrecomillados con prefijos:

Literal Ejemplo Descripción
Bytes
  • B"abc"
  • B'''abc'''
  • b"""abc"""
Los literales con comillas o comillas triples que tienen el prefijo de literal de bytes (b o B) se interpretan como bytes.
Bytes sin procesar
  • br'abc+'
  • RB"abc+"
  • RB'''abc'''
Los prefijos r y b se pueden combinar en cualquier orden. Por ejemplo, rb'abc*' es equivalente a br'abc*'.

En la siguiente tabla, se enumeran todas las secuencias de escape válidas para representar caracteres no alfanuméricos en literales de string y de bytes. Cualquier secuencia que no esté en esta tabla genera un error.

Secuencia de escape Descripción
\a Bell
\b Retroceso
\f Salto de página
\n Nueva línea
\r Retorno de carro
\t Tabulación
\v Tabulación vertical
\\ Barra invertida (\)
\? Signo de interrogación (?)
\" Comillas dobles (")
\' Comillas simples (')
\` Acento grave (`)
\ooo Escape octal con 3 dígitos (en el rango 0–7). Se decodifica como solo carácter Unicode (en literales de string) o byte (en literales de bytes).
\xhh o \Xhh Escape hexadecimal con 2 dígitos hexadecimales (0–9 y A–F o a–f). Se decodifica como solo carácter Unicode (en literales de string) o byte (en literales de bytes). Por ejemplo:
  • '\x41' == 'A'
  • '\x41B' es 'AB'
  • '\x4' es un error
\uhhhh Escape de Unicode, con una “u” en minúscula y 4 dígitos hexadecimales. Solo es válido en literales de string o identificadores.
Ten en cuenta que el rango D800-DFFF no está permitido, ya que estos son valores unicode subrogados.
\Uhhhhhhhh Escape de Unicode, con una “U” mayúscula y 8 dígitos hexadecimales. Válido solo en literales de string o identificadores.
El rango D800-DFFF no está permitido, ya que estos valores son valores unicode subrogados. Además, no se permiten valores superiores a 10FFFF.

Literales de número entero

Los literales de números enteros son una secuencia de dígitos decimales (0-9) o un valor hexadecimal con el prefijo “0x” o “0X”. Los números enteros pueden tener el prefijo “+” o “-” para representar los valores positivos y negativos, respectivamente. Por ejemplo:

123
0xABC
-123

Un literal de número entero se interpreta como INT64.

Literales NUMERIC

Puedes construir literales NUMERIC con la palabra clave NUMERIC seguida de un valor de punto flotante entre comillas.

Ejemplos:

SELECT NUMERIC '0';
SELECT NUMERIC '123456';
SELECT NUMERIC '-3.14';
SELECT NUMERIC '-0.54321';
SELECT NUMERIC '1.23456e05';
SELECT NUMERIC '-9.876e-3';

Literales de punto flotante

Opciones de sintaxis:

[+-]DIGITS.[DIGITS][e[+-]DIGITS]
[DIGITS].DIGITS[e[+-]DIGITS]
DIGITSe[+-]DIGITS

DIGITS representa uno o más números decimales (0 a 9) y e representa el marcador de exponente (e o E).

Por ejemplo:

123.456e-67
.1E4
58.
4e2

Se supone que los literales numéricos que contienen un punto decimal o un marcador de exponente son de tipo doble.

Es posible la conversión implícita de los literales de punto flotante en tipo flotante si el valor está dentro del rango flotante válido.

No hay una representación literal de NaN o infinito, pero las siguientes string sin distinción entre mayúsculas y minúsculas se pueden convertir de forma explícita en flotantes:

  • “NaN”
  • “inf” o “+inf”
  • “-inf”

Literales de arreglo

Los literales de arreglo son listas de elementos separados por comas entre corchetes. La palabra clave ARRAY y un tipo de elemento T explícito son opcionales.

Ejemplos:

[1, 2, 3]
['x', 'y', 'xy']
ARRAY[1, 2, 3]
ARRAY<string>['x', 'y', 'xy']
ARRAY<int64>[]

Literales de struct

Sintaxis:

(elem[, elem...])

En el ejemplo anterior, elem es un elemento de struct y elem debe ser un tipo de datos literal, no una expresión o nombre de columna.

El resultado tiene un tipo de struct anónimo (los structs no son tipos con nombre) con campos anónimos que tienen tipos que coinciden con los de las expresiones de entrada.

Ejemplo Tipo de salida
(1, 2, 3) STRUCT<int64,int64,int64>
(1, 'abc') STRUCT<int64,string>

Literales de fecha

Sintaxis:

DATE 'YYYY-M[M]-D[D]'

Los literales de fecha contienen la palabra clave DATE seguida de un literal de string que se ajusta al formato de fecha canónico y está encerrado entre comillas simples. Los literales de fecha admiten un rango entre los años 1 y 9999, inclusive. Las fechas fuera de este rango no son válidas.

Por ejemplo, el siguiente literal de fecha representa el 27 de septiembre de 2014:

DATE '2014-09-27'

Los literales de string en formato de fecha canónico también se convierten de forma implícita en el tipo DATE si se usan cuando se espera una expresión de tipo DATE. Por ejemplo, en la consulta siguiente:

SELECT * FROM foo WHERE date_col = "2014-09-27"

el literal de string "2014-09-27" se convertirá en un literal de fecha.

Literales de hora

Sintaxis:

TIME '[H]H:[M]M:[S]S[.DDDDDD]]'

Los literales TIME contienen la palabra clave TIME y un literal de string que se ajusta al formato de hora canónico y está encerrado entre comillas simples.

Por ejemplo, la siguiente hora representa las 12:30 p.m.:

TIME '12:30:00.45'

Literales de fecha y hora

Sintaxis:

DATETIME 'YYYY-[M]M-[D]D [[H]H:[M]M:[S]S[.DDDDDD]]'

Los literales de fecha y hora contienen la palabra clave DATETIME y un literal de string que se ajusta al formato de marca de fecha y hora canónica y está encerrada entre comillas simples.

Por ejemplo, la siguiente fecha y hora representa las 12:30 p.m. del 27 de septiembre de 2014:

DATETIME '2014-09-27 12:30:00.45'

Los literales de fecha y hora admiten un rango entre los años 1 y 9999, inclusive. Las fechas y horas fuera de este rango no son válidos.

Los literales de string con el formato canónico de fecha y hora se convierten de forma implícita en un literal de fecha y hora si se usan cuando se espera una expresión de fecha y hora.

Por ejemplo:

SELECT * FROM foo
WHERE datetime_col = "2014-09-27 12:30:00.45"

En la consulta anterior, el literal de string "2014-09-27 12:30:00.45" se convierte en un literal de fecha y hora.

Un literal de fecha y hora también puede incluir el carácter opcional T o t. Esta es una marca de tiempo y se usa como separador entre la fecha y la hora. Si usas este carácter, no se puede incluir un espacio ni antes ni después. Los siguientes literales son válidos:

DATETIME '2014-09-27T12:30:00.45'
DATETIME '2014-09-27t12:30:00.45'

Literales de marca de tiempo

Sintaxis:

TIMESTAMP 'YYYY-[M]M-[D]D [[H]H:[M]M:[S]S[.DDDDDD] [timezone]]'

Los literales de marca de tiempo contienen la palabra clave TIMESTAMP y un literal de string que se ajusta al formato de marca de tiempo canónico y está encerrado entre comillas simples.

Los literales de marca de tiempo admiten un rango entre los años 1 y 9999, inclusive. Las marcas de tiempo fuera de este rango no son válidas.

Un literal de marca de tiempo puede incluir un sufijo numérico para indicar la zona horaria:

TIMESTAMP '2014-09-27 12:30:00.45-08'

Si este sufijo está ausente, se usa la zona horaria predeterminada, UTC.

Por ejemplo, la siguiente marca de tiempo representa las 12:30 p.m. del 27 de septiembre de 2014 con la zona horaria UTC:

TIMESTAMP '2014-09-27 12:30:00.45'

Consulta las zonas horarias para obtener más información.

Los literales de string con el formato de marca de tiempo canónico, incluidos los que tienen nombres de zona horaria, se convierten de forma implícita en un literal de marca de tiempo si se usan cuando se espera una expresión de marca de tiempo. Por ejemplo, en la siguiente consulta, el literal de string "2014-09-27 12:30:00.45 America/Los_Angeles" se convierte en un literal de marca de tiempo.

SELECT * FROM foo
WHERE timestamp_col = "2014-09-27 12:30:00.45 America/Los_Angeles"

Un literal de marca de tiempo puede incluir estos caracteres opcionales:

  • T o t: una marca de tiempo. Se usa como separador entre la fecha y la hora.
  • Z o z: una marca para la zona horaria predeterminada. No se puede usar con [timezone].

Si usas uno de estos caracteres, no se puede incluir un espacio ni antes ni después. Los siguientes literales son válidos:

TIMESTAMP '2017-01-18T12:34:56.123456Z'
TIMESTAMP '2017-01-18t12:34:56.123456'
TIMESTAMP '2017-01-18 12:34:56.123456z'
TIMESTAMP '2017-01-18 12:34:56.123456Z'

Zona horaria

Debido a que los literales de marca de tiempo deben asignarse a un momento específico, se necesita una zona horaria para interpretarlos de forma correcta. Si no se especifica una zona horaria como parte del literal, se usa el valor de zona horaria predeterminado que se establece con la implementación de BigQuery.

BigQuery representa zonas horarias mediante strings en el siguiente formato canónico, que representa la diferencia con el tiempo universal coordinado (UTC).

Formato:

(+|-)H[H][:M[M]]

Por ejemplo:

'-08:00'
'-8:15'
'+3:00'
'+07:30'
'-7'

Las zonas horarias también se pueden expresar mediante nombres de zona horaria de string de la base de datos tz. Si prefieres una referencia menos completa, pero más simple, consulta la lista de zonas horarias de la base de datos tz en Wikipedia. Los nombres de zonas horarias canónicos tienen el formato <continent/[region/]city>, como America/Los_Angeles.

Ejemplo:

TIMESTAMP '2014-09-27 12:30:00 America/Los_Angeles'
TIMESTAMP '2014-09-27 12:30:00 America/Argentina/Buenos_Aires'

Distinción de mayúsculas

BigQuery sigue estas reglas para la distinción entre mayúsculas y minúsculas:

Categoría ¿Distingue mayúsculas de minúsculas? Notas
Palabras clave No  
Nombres de funciones integradas No  
Nombres de funciones definidas por el usuario  
Nombres de tablas  
Nombres de columnas No  
Valores de string
Comparaciones de strings  
Alias dentro de una consulta No  
Coincidencia de expresiones regulares Ver las notas La coincidencia de expresiones regulares distingue entre mayúsculas y minúsculas de forma predeterminada, a menos que la expresión misma especifique que no realiza esta distinción.
Coincidencia de LIKE  

Palabras clave reservadas

Las palabras clave son un grupo de tokens con un significado especial en el lenguaje de BigQuery y tienen las siguientes características:

  • Las palabras clave no se pueden usar como identificadores, a menos que estén encerradas entre caracteres de acento grave (`).
  • Las palabras clave no distinguen entre mayúsculas y minúsculas.

BigQuery tiene las siguientes palabras clave reservadas.

ALL
AND
ANY
ARRAY
AS
ASC
ASSERT_ROWS_MODIFIED
AT
BETWEEN
BY
CASE
CAST
COLLATE
CONTAINS
CREATE
CROSS
CUBE
CURRENT
DEFAULT
DEFINE
DESC
DISTINCT
ELSE
END
ENUM
ESCAPE
EXCEPT
EXCLUDE
EXISTS
EXTRACT
FALSE
FETCH
FOLLOWING
FOR
FROM
FULL
GROUP
GROUPING
GROUPS
HASH
HAVING
IF
IGNORE
IN
INNER
INTERSECT
INTERVAL
INTO
IS
JOIN
LATERAL
LEFT
LIKE
LIMIT
LOOKUP
MERGE
NATURAL
NEW
NO
NOT
NULL
NULLS
OF
ON
OR
ORDER
OUTER
OVER
PARTITION
PRECEDING
PROTO
RANGE
RECURSIVE
RESPECT
RIGHT
ROLLUP
ROWS
SELECT
SET
SOME
STRUCT
TABLESAMPLE
THEN
TO
TREAT
TRUE
UNBOUNDED
UNION
UNNEST
USING
WHEN
WHERE
WINDOW
WITH
WITHIN

Punto y coma final

De forma opcional, puedes usar un punto y coma final (;) cuando envíes una instrucción de string de consulta a través de una interfaz de programación de aplicaciones (API).

En una solicitud que contiene múltiples instrucciones, debes separarlas con punto y coma, pero, por lo general, este símbolo es opcional después de la instrucción final. Algunas herramientas interactivas requieren que las instrucciones tengan un punto y coma final.

Comas finales

De manera opcional, puedes usar una coma final (,) luego de una lista en una declaración SELECT.

Ejemplo

SELECT name, release_date, FROM Books

Parámetros de consulta

Puedes usar parámetros de consulta para sustituir expresiones arbitrarias. Sin embargo, los parámetros de consulta no se pueden usar para sustituir identificadores, nombres de columnas, nombres de tablas ni otras partes de la consulta. Los parámetros de consulta se definen fuera de la declaración de consulta.

Las API de cliente permiten la vinculación de nombres de parámetros a valores; el motor de consultas sustituye un valor vinculado por un parámetro en el momento de la ejecución.

Los parámetros de consulta no se pueden usar en el cuerpo de SQL de estas instrucciones: CREATE FUNCTION, CREATE VIEW, CREATE MATERIALIZED VIEW y CREATE PROCEDURE.

Parámetros de consulta con nombre

Sintaxis:

@parameter_name

Un parámetro de consulta con nombre se denota mediante un identificador precedido por el carácter @. Los parámetros de consulta con nombre no se pueden usar junto con los parámetros de consulta posicionales.

Ejemplo:

En este ejemplo, se muestran todas las filas en las que LastName es igual al valor del parámetro de consulta con nombre myparam.

SELECT * FROM Roster WHERE LastName = @myparam

Parámetros de consulta posicionales

Los parámetros de consulta posicionales se indican con el carácter ?. Los parámetros posicionales se evalúan según el orden en el que se pasan. Los parámetros de consulta posicionales no se pueden usar junto con los parámetros de consulta con nombre.

Ejemplo:

Esta consulta muestra todas las filas en las que LastName y FirstName son iguales a los valores pasados a esta consulta. El orden en el que se pasan estos valores es importante. Si el último nombre se pasa primero, seguido del primer nombre, no se mostrarán los resultados esperados.

SELECT * FROM Roster WHERE FirstName = ? and LastName = ?

Comentarios

Los comentarios son secuencias de caracteres que el analizador ignora. BigQuery admite los siguientes tipos de comentarios.

Comentarios de una línea

Usa un comentario de una línea si deseas que aparezca en una línea solo.

Ejemplos

# this is a single-line comment
SELECT book FROM library;
-- this is a single-line comment
SELECT book FROM library;
/* this is a single-line comment */
SELECT book FROM library;
SELECT book FROM library
/* this is a single-line comment */
WHERE book = "Ulysses";

Comentarios intercalados

Usa un comentario intercalado si deseas que aparezca en la misma línea que una instrucción. Un comentario precedido por # o -- debe aparecer a la derecha de una instrucción.

Ejemplos

SELECT book FROM library; # this is an inline comment
SELECT book FROM library; -- this is an inline comment
SELECT book FROM library; /* this is an inline comment */
SELECT book FROM library /* this is an inline comment */ WHERE book = "Ulysses";

Comentarios de varias líneas

Usa un comentario de varias líneas si necesitas que abarque múltiples líneas. No se admiten los comentarios de varias líneas anidados.

Ejemplos

SELECT book FROM library
/*
  This is a multiline comment
  on multiple lines
*/
WHERE book = "Ulysses";
SELECT book FROM library
/* this is a multiline comment
on two lines */
WHERE book = "Ulysses";