Estrutura lexical do SQL padrão

No BigQuery, uma instrução é composta de vários tokens, Eles incluem identificadores, identificadores entre aspas, literais, palavras-chave, operadores e caracteres especiais. É possível separar tokens com comentários ou um espaço em branco, por exemplo, espaço, backspace, tabulação ou nova linha.

Identificadores

São nomes associados a colunas, tabelas e outros objetos do banco de dados. Eles podem estar entre aspas ou não.

  • Os identificadores podem ser usados em expressões de caminho que retornam um STRUCT.
  • Alguns identificadores diferenciam maiúsculas de minúsculas e outros não. Para detalhes, consulte Diferença entre maiúsculas e minúsculas.
  • Identificadores sem aspas devem começar com uma letra ou um caractere sublinhado. Os caracteres seguintes podem ser letras, números ou sublinhados.
  • Os identificadores entre aspas precisam ser colocados entre caracteres de crase (`).
    • Os identificadores entre aspas podem conter qualquer caractere, como espaços ou símbolos.
    • Os identificadores entre aspas não podem estar vazios.
    • Os identificadores entre aspas têm as mesmas sequências de escape dos literais de strings.
    • Uma palavra-chave reservada precisa ser um identificador entre aspas se for uma palavra-chave independente ou o primeiro componente de uma expressão de caminho. Ela pode estar sem aspas como o segundo ou posterior componente de uma expressão de caminho.
  • Os identificadores de nome da tabela têm sintaxe adicional para serem compatíveis com traços (-) quando referenciados nas cláusulas FROM e TABLE.

Exemplos

Estes são identificadores válidos:

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

Essas expressões de caminho contêm identificadores válidos:

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

Estes são identificadores inválidos:

5Customers
_dataField!
GROUP

5Customers começa com um número, não uma letra ou um sublinhado. _dataField! contém o caractere especial "!" que não é uma letra, um número ou um sublinhado. GROUP é uma palavra-chave reservada e, portanto, não pode ser usada como identificador sem estar entre caracteres de crase.

Não é necessário inserir nomes de tabelas que incluam traços com acentos graves. Eles são equivalentes:

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

Literais

Os literais representam um valor constante de um tipo de dados integrado. Alguns tipos de dados podem ser expressos como literais, mas nem todos.

Literais de strings e bytes

Os literais de string e de bytes precisam ficar entre aspas, com aspas simples (') ou duplas (") ou, ainda, aspas triplas com grupos de três aspas simples (''') ou três duplas (""").

Literais entre aspas:

Literal Exemplos Descrição
String entre aspas
  • "abc"
  • "it's"
  • 'it\'s'
  • 'Title: "Boy"'
Strings entre aspas simples (') podem conter aspas duplas sem escape ("), assim como o inverso. As
barras invertidas (\) iniciam as sequências de escape. Veja a tabela "Sequências de escape" abaixo.
As strings entre aspas não podem ter novas linhas, mesmo se precedidas de barra invertida (\).
String entre três aspas
  • """abc"""
  • '''it's'''
  • '''Title:"Boy"'''
  • '''two
    lines'''
  • '''why\?'''
As novas linhas e aspas incorporadas são permitidas sem escapes. Veja o quarto exemplo. As
barras invertidas (\) iniciam as sequências de escape. Veja a tabela "Sequências de escape" abaixo.
Não é permitida uma barra invertida (\) sem escape no final de uma linha.
Encerre a string com três aspas sem escape em uma linha que correspondam às aspas iniciais.
String bruta
  • R"abc+"
  • r'''abc+'''
  • R"""abc+"""
  • r'f\(abc,(.*),def\)'
Os literais entre aspas ou aspas triplas que têm o prefixo do literal de string bruta (r ou R) são interpretados como strings brutas/regex.
Os caracteres de barra invertida (\) não funcionam como caracteres de escape. Se uma barra invertida seguida por outro caractere for usada dentro do literal de string, os dois caracteres serão preservados.
As strings brutas não podem terminar com um número ímpar de barras invertidas.
As strings brutas são úteis para construir expressões regulares.

Os caracteres de prefixo (r, R, b, B)) são opcionais para strings entre aspas ou três aspas e indicam que a string é do tipo bruta/regex ou uma sequência de bytes, respectivamente. Por exemplo, b'abc' e b'''abc''' são interpretados como bytes de tipo. Os caracteres de prefixo diferenciam maiúsculas de minúsculas.

Literais entre aspas com prefixos:

Literal Exemplo Descrição
Bytes
  • B"abc"
  • B'''abc'''
  • b"""abc"""
Os literais entre aspas ou aspas triplas com o prefixo de literal de bytes (b ou B) são interpretados como bytes.
Bytes brutos
  • br'abc+'
  • RB"abc+"
  • RB'''abc'''
Os prefixos r e b podem ser combinados em qualquer ordem. Por exemplo, rb'abc*' equivale a br'abc*'.

Na tabela a seguir, veja todas as sequências de escape válidas para representar caracteres não alfanuméricos em literais de strings e bytes. Qualquer sequência que não esteja nesta tabela resulta em erro.

Sequência de escape Descrição
\a Aviso sonoro
\b Backspace
\f Avanço de formulário
\n Nova linha
\r Retorno de carro
\t Tabulação
\v Tabulação vertical
\\ Barra invertida (\)
\? Ponto de interrogação (?)
\" Aspas duplas (")
\' Aspas simples (')
\` Acento grave (`)
\ooo Escape octal, com exatamente três dígitos (no intervalo de 0 a 7). É decodificado como um único caractere Unicode (em literais de strings) ou byte (em literais de bytes).
\xhh ou \Xhh Escape hexadecimal, com exatamente dois dígitos hexadecimais (0–9 ou A–F ou a–f). É decodificado como um único caractere Unicode (em literais de strings) ou byte (em literais de bytes). Exemplos:
  • '\x41' == 'A'
  • '\x41B' é 'AB'
  • '\x4' é um erro
\uhhhh Escape Unicode, com "u" minúsculo e exatamente quatro dígitos hexadecimais. Válido apenas em literais de string ou identificadores.
Observação: o intervalo D800-DFFF não é permitido, já que são valores unicode alternativos.
\Uhhhhhhhh Escape Unicode, com "U" maiúsculo e exatamente oito dígitos hexadecimais. Válido apenas em literais de string ou identificadores.
O intervalo D800-DFFF não é permitido, pois são valores unicode alternativos. Além disso, valores maiores que 10FFFF não são permitidos.

Literais de inteiros

Literais de inteiros são uma sequência de dígitos decimais (de 0 a 9) ou um valor hexadecimal com prefixo "0x" ou "0X". Os inteiros podem ter o prefixo "+" ou "-" para representar valores positivos e negativos, respectivamente. Exemplos:

123
0xABC
-123

Um literal de inteiro é interpretado como INT64.

Literais NUMERIC

Crie literais NUMERIC usando a palavra-chave NUMERIC seguida de um valor de ponto flutuante entre aspas.

Exemplos:

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

Literais de ponto flutuante

Opções de sintaxe:

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

DIGITS representa um número decimal (de 0 a 9) ou mais, e e representa o rótulo expoente (e ou E).

Exemplos:

123.456e-67
.1E4
58.
4e2

Supõe-se que os literais numéricos que contêm um ponto decimal ou um rótulo expoente sejam do tipo duplo.

A coerção implícita de literais de ponto flutuante para o tipo flutuante será possível se o valor estiver dentro do intervalo flutuante válido.

Não há representação literal de NaN ou infinitude, mas é possível fazer o cast para flutuante das strings que diferenciam entre maiúsculas e minúsculas a seguir:

  • "NaN"
  • "inf" ou "+inf"
  • "-inf"

Literais de matriz

Literais de matriz são listas separadas por vírgulas de elementos entre colchetes. A palavra-chave ARRAY é opcional, assim como um tipo de elemento T explícito.

Exemplos:

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

Literais struct

Sintaxe:

(elem[, elem...])

em que elemé um elemento no struct. elem precisa ser um tipo de dados de literal, não uma expressão ou nome de coluna.

O tipo de saída é de struct anônimo (structs são tipos não nomeados) com campos anônimos contendo tipos que correspondem aos existentes nas expressões de entrada.

Exemplo Tipo de saída
(1, 2, 3) STRUCT<int64,int64,int64>
(1, 'abc') STRUCT<int64,string>

Literais de data

Sintaxe:

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

Literais de data contêm a palavra-chave DATE seguida de um literal de string em conformidade com o formato de data canônico e ficam entre aspas simples. Os literais de data, inclusive, aceitam um intervalo entre os anos 1 e 9999. As datas fora desse intervalo são inválidas.

Por exemplo, o literal de data a seguir representa 27 de setembro de 2014:

DATE '2014-09-27'

Os literais de strings no formato de data canônico também forçam, implicitamente, o tipo DATE quando usados se uma expressão do tipo DATE for esperada. Por exemplo, na consulta

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

o literal de string "2014-09-27" será forçado para um literal de data.

Literais de hora

Sintaxe:

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

Os literais de hora contêm a palavra-chave TIME e um literal de string em conformidade com o formato de hora canônico e ficam entre aspas simples.

Por exemplo, este horário representa 12h30:

TIME '12:30:00.45'

Literais datetime

Sintaxe:

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

Os literais datetime contêm a palavra-chave DATETIME e um literal de string em conformidade com o formato datetime canônico e ficam entre aspas simples.

Por exemplo, este datetime representa 12h30 em 27 de setembro de 2014:

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

Os literais datetime aceitam um intervalo entre os anos 1 e 9999, inclusive. Datetimes fora desse intervalo são inválidos.

Os literais de strings no formato datetime canônico também forçam, implicitamente, o literal datetime quando usados se uma expressão do tipo datetime for esperada.

Exemplo:

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

Na consulta acima, o literal de string "2014-09-27 12:30:00.45" é forçado a um literal datetime.

Um literal datetime também pode incluir o caractere opcional T ou t. Esta é uma sinalização de hora e é usada como separador entre a data e a hora. Se você usar esse caractere, um espaço não poderá ser incluído antes ou depois dele. Estes são válidos:

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

Literais de timestamp

Sintaxe:

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

Os literais de carimbo de data/hora contêm a palavra-chave TIMESTAMP e um literal de string em conformidade com o formato de carimbo de data/hora canônico e ficam entre aspas simples.

Os literais de carimbo de data/hora aceitam um intervalo entre os anos 1 e 9999, inclusive. Carimbos de data/hora fora desse intervalo são inválidos.

Um literal de carimbo de data/hora pode incluir um sufixo numérico para indicar o fuso horário:

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

Se esse sufixo estiver ausente, será usado o fuso horário padrão, UTC.

Por exemplo, este carimbo de data/hora representa 12h30 de 27 de setembro de 2014, usando o fuso horário UTC:

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

Para ver mais informações de fusos horários, veja Fuso horário.

Literais de string com o formato de carimbo de data/hora canônico, incluindo aqueles com nomes de fusos horários, forçam implicitamente um literal de carimbo de data/hora quando usados se uma expressão de carimbo de data/hora for esperada. Por exemplo, na consulta a seguir, o literal de string "2014-09-27 12:30:00.45 America/Los_Angeles" é forçado para um literal de carimbo de data/hora.

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

Um literal de carimbo de data/hora pode incluir estes caracteres opcionais:

  • T ou t: uma sinalização de tempo. Use como separador entre a data e a hora.
  • Z ou z: uma sinalização para o fuso horário padrão. Não é possível usar com [timezone].

Se você usar um desses caracteres, um espaço não poderá ser incluído antes ou depois dele. Estes são 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'

Fuso horário

Devido à obrigatoriedade de mapear os literais de carimbo de data/hora para um ponto específico no tempo, um fuso horário é necessário para interpretar corretamente um literal. Se um fuso horário não for especificado como parte do próprio literal, o BigQuery usará o valor do fuso horário padrão, definido pela implementação do BigQuery.

O BigQuery representa os fusos horários usando strings no formato canônico a seguir, que representa o deslocamento do Tempo Universal Coordenado (UTC).

Formato:

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

Exemplos:

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

Os fusos horários também podem ser expressos com strings de nomes de fusos horários do tz database. Para ter uma referência menos explicativa, porém mais simples, veja a Lista de fusos horários do tz database (em inglês) na Wikipédia. Os nomes de fusos horários canônicos têm o formato <continent/[region/]city>, como America/Los_Angeles.

Exemplo:

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

Diferenciação entre maiúsculas e minúsculas

As regras de diferenciação de maiúsculas e minúsculas aplicam-se ao BigQuery:

Categoria Diferenciação entre maiúsculas e minúsculas? Observações
Palavras-chave Não  
Nomes de funções integradas Não  
Nomes de funções definidas pelo usuário Sim  
Nomes de tabela Sim  
Nomes de colunas Não  
Valores de strings Sim
Comparações de strings Sim  
Aliases dentro de uma consulta Não  
Correspondência com expressões regulares Consulte as observações A expressão regular correspondente diferencia maiúsculas de minúsculas por padrão, a menos que a própria expressão especifique que ela não pode fazer essa diferenciação.
Correspondência com LIKE Sim  

Palavras-chave reservadas

Palavras-chave são um grupo de tokens com significado especial na linguagem do BigQuery, e têm as seguintes características:

  • Não é possível usar palavras-chave como identificadores a menos que estejam entre caracteres de crase (`).
  • As palavras-chave não diferenciam maiúsculas de minúsculas.

O BigQuery tem as palavras-chave reservadas a seguir.

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

Ponto e vírgula de terminação

Como opção, as instruções de string de consulta podem terminar com ponto e vírgula (;) quando enviadas por meio da Interface de Programação do Aplicativo (API).

Em solicitações com várias instruções, elas precisam ser separadas por ponto e vírgula, que costuma ser opcional após a instrução final. Em algumas ferramentas interativas, é necessário que as instruções terminem com ponto e vírgula.

Vírgulas à direita

É possível usar uma vírgula à direita (,) no final de uma lista em uma instrução SELECT.

Exemplo

SELECT name, release_date, FROM Books

Parâmetros de consulta

Use parâmetros de consulta para substituir expressões arbitrárias. No entanto, parâmetros de consulta não podem ser usados para substituir identificadores, nomes de colunas, nomes de tabelas ou outras partes da própria consulta. Parâmetros de consulta são definidos fora da instrução de consulta.

As APIs do cliente permitem a vinculação de nomes de parâmetros a valores; o mecanismo de consulta substitui um valor vinculado por um parâmetro no momento da execução.

Parâmetros de consulta não podem ser usados no corpo SQL dessas instruções: CREATE FUNCTION, CREATE VIEW, CREATE MATERIALIZED VIEW e CREATE PROCEDURE.

Parâmetros de consulta nomeados

Sintaxe:

@parameter_name

Um parâmetro de consulta nomeado é indicado com o uso de um identificador precedido pelo caractere @. Não é possível usar parâmetros de consulta nomeados com [positional query parameters][positional- query-parameters].

Exemplo:

Este exemplo retorna todas as linhas em que LastName é igual ao valor do parâmetro de consulta nomeado myparam.

SELECT * FROM Roster WHERE LastName = @myparam

Parâmetros de consulta posicionais

Parâmetros de consulta posicionais são indicados usando o caractere ?. Eles são avaliados pela ordem em que são transmitidos. E não podem ser usados com parâmetros de consulta nomeados.

Exemplo:

Essa consulta retorna todas as linhas em que LastName e FirstName são iguais aos valores passados para essa consulta. A ordem em que esses valores são passados é importante. Se o último nome for passado primeiro, seguido pelo nome, os resultados esperados não serão retornados.

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

Comentários

Comentários são sequências de caracteres ignoradas pelo analisador. O BigQuery é compatível com os tipos de comentários a seguir.

Comentários de linha única

Use um comentário de linha única se quiser que o comentário apareça apenas em uma linha.

Exemplos

# 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";

Comentários in-line

Use um comentário in-line se quiser que ele apareça na mesma linha da instrução. Comentários precedidos por # ou -- têm que aparecer à direita das instruções.

Exemplos

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";

Comentários de várias linhas

Use um comentário de várias linhas se precisar que o comentário inclua várias linhas. Comentários de várias linhas aninhados não são compatíveis.

Exemplos

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";