Tipos de dados no SQL padrão

O BigQuery é compatível com tipos de dados simples, como inteiros, e com tipos mais complexos, como ARRAY e STRUCT. Nesta página, apresentamos uma visão geral de cada tipo de dados, incluindo valores permitidos. Para informações sobre literais e construtores de tipos de dados, consulte Estrutura léxica e sintaxe.

Propriedades do tipo de dados

Ao armazenar e consultar dados, vale a pena ter em mente as seguintes propriedades de tipos de dados:

Propriedade Descrição É aplicável a
Anulável NULL é um valor válido. Todos os tipos de dados, com as seguintes exceções:
  • ARRAYs não podem ser NULL.
  • Elementos NULL ARRAY não podem permanecer em uma tabela.
Ordenável Pode ser usado em uma cláusula ORDER BY. Todos os tipos de dados, exceto:
  • ARRAY
  • STRUCT
  • GEOGRAPHY
Agrupável Geralmente, podem aparecer em uma expressão após
GROUP BY, DISTINCT e PARTITION BY.
No entanto, as expressões PARTITION BY não podem incluir
tipos de ponto flutuante.
Todos os tipos de dados, exceto:
  • ARRAY
  • STRUCT
  • GEOGRAPHY
Comparável Valores do mesmo tipo podem ser comparados entre si. Todos os tipos de dados, com as seguintes exceções: comparações de ARRAY não são aceitas.

Comparações de igualdade para STRUCTs são compatíveis campo por campo, na ordem dos campos. Nomes de campos são ignorados. As comparações "menor que" e "maior que" não são aceitas.

As comparações de GEOGRAPHY são incompatíveis. Para comparar valores de GEOGRAPHY, use ST_Equals.

Todos os tipos compatíveis com comparações podem ser usados em uma condição JOIN. Consulte Tipos de JOIN para uma explicação sobre condições de mesclagem.

Tipos numéricos

Entre tipos numéricos estão tipos inteiros, tipos de ponto flutuante e os dados NUMERIC.

Tipo inteiro

Inteiros são valores numéricos que não têm componentes fracionários.

Nome Range
INT64 -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807

Tipo NUMERIC

O tipo de dados NUMERIC é um valor numérico exato com 38 dígitos de precisão e 9 dígitos decimais de escala. A precisão é o número de dígitos que o número contém. A escala indica quantos desses dígitos ficam após o ponto decimal.

Esse tipo pode representar exatamente as frações decimais e é adequado para cálculos financeiros.

Nome Descrição Range
NUMERIC Valores decimais com 38 dígitos decimais de precisão e 9 dígitos decimais de escala. -99999999999999999999999999999.999999999 a 99999999999999999999999999999.999999999

Tipo ponto flutuante

Valores de ponto flutuante são valores numéricos aproximados com componentes fracionários.

Nome Descrição
FLOAT64 Valores decimais de precisão dupla (aproximada).

Semântica de ponto flutuante

Ao trabalhar com números de ponto flutuante, há valores não numéricos especiais que precisam ser considerados: NaN e +/-inf.

Operadores aritméticos proporcionam comportamento IEEE-754 padrão a todos os valores de entrada finitos que produzem saída finita e a todas as operações para as quais pelo menos uma entrada é não finita.

Chamadas de função e operadores retornam um erro de estouro quando a entrada é finita, mas a saída pode ser não finita. Se a entrada contém valores não finitos, a saída pode ser não finita. Em geral, as funções não introduzem NaNs ou +/-inf. No entanto, funções específicas como IEEE_DIVIDE podem retornar valores não finitos em entrada finita. Todos esses casos são evidenciados explicitamente em funções matemáticas.

Exemplos de funções matemáticas
Termo esquerdo Operador Termo direito Retorna
Qualquer valor + NaN NaN
1,0 + +inf +inf
1,0 + -inf -inf
-inf + +inf NaN
Valor máximo de FLOAT64 + Valor máximo de FLOAT64 Erro de estouro
Valor mínimo de FLOAT64 / 2,0 0,0
1,0 / 0.0 Erro "divisão por zero"

Operadores de comparação proporcionam comportamento IEEE-754 padrão à entrada de ponto flutuante.

Exemplos de operadores de comparação
Termo esquerdo Operador Termo direito Retorna
NaN = Qualquer valor FALSE
NaN < Qualquer valor FALSE
Qualquer valor < NaN FALSE
-0,0 = 0,0 TRUE
-0,0 < 0,0 FALSE

Valores em pontos flutuantes são classificados nesta ordem, do menor para o maior:

  1. NULL
  2. NaN: todos os valores de NaN são considerados iguais na classificação.
  3. -inf
  4. Números negativos
  5. 0 ou -0 — todos os valores zero são considerados iguais no momento da classificação.
  6. Números positivos
  7. +inf

Valores em pontos flutuantes especiais são agrupados dessa forma, incluindo o agrupamento feito por uma cláusula GROUP BY e o agrupamento feito pela palavra-chave DISTINCT:

  • NULL
  • NaN: todos os valores NaN são considerados iguais no agrupamento.
  • -inf
  • 0 ou -0 — todos os valores zero são considerados iguais no momento do agrupamento.
  • +inf

Tipo booleano

Nome Descrição
BOOL Valores booleanos são representados pelas palavras-chave TRUE e FALSE (sem distinção de maiúsculas e minúsculas).

Tipo de string

Nome Descrição
STRING Dados em caracteres de comprimento variável (Unicode).

Os valores STRING de entrada precisam ter codificação UTF-8, e os valores STRING de saída terão codificação UTF-8. Codificações alternativas como CESU-8 e UTF-8 modificado não são tratadas como UTF-8 válida.

Todas as funções e operadores que atuam sobre valores STRING atuam sobre caracteres Unicode em vez de bytes. Por exemplo, funções como SUBSTR e LENGTH aplicadas à entrada STRING contam o número de caracteres, não os bytes.

Cada caractere Unicode tem um valor numérico chamado de ponto de código atribuído a ele. Pontos de código inferiores são atribuídos a caracteres menores. Quando os caracteres são comparados, os pontos de código determinam quais caracteres são menores ou maiores que os outros caracteres.

A maioria das funções em STRING também é definida em BYTES. A versão BYTES opera em bytes brutos em vez de caracteres Unicode. STRING e BYTES são tipos distintos que não podem ser usados alternadamente. Não ocorre cast implícito em nenhuma direção. O cast explícito entre STRING e BYTES faz codificação e decodificação UTF-8. O cast de BYTES para STRING retorna um erro quando os bytes não estão em UTF-8 válido.

Tipo bytes

Nome Descrição
BYTES Dados binários de comprimento variável.

STRING e BYTES são tipos distintos que não podem ser usados alternadamente. A maioria das funções em STRING também é definida em BYTES. A versão BYTES opera em bytes brutos em vez de caracteres Unicode. Casts entre STRING e BYTES impõem que os bytes sejam codificados usando UTF-8.

Tipo date

Nome Intervalo
DATE De 0001-01-01 a 9999-12-31.

O tipo DATE representa uma data de calendário lógico, independente do fuso horário. Um valor DATE não representa um período de tempo específico de 24 horas. Em vez disso, representa um período diferente de 24 horas quando interpretado em fusos horários diferentes, podendo representar um dia mais curto ou mais longo durante as transições de horário de verão. Para representar um ponto absoluto no tempo, use um carimbo de data/hora.

Formato canônico
'YYYY-[M]M-[D]D'
  • YYYY: ano de quatro dígitos
  • [M]M: mês de um ou dois dígitos.
  • [D]D: dia de um ou dois dígitos

Tipo datetime

Nome Intervalo
DATETIME De 0001-01-01 00:00:00 a 9999-12-31 23:59:59,999999

Um objeto DATETIME representa uma data e uma hora, do modo como elas são exibidas em um calendário ou relógio, independentemente do fuso horário. Inclui ano, mês, dia, hora, minuto, segundo e subsegundo. Para representar um ponto absoluto no tempo, use um carimbo de data/hora.

Formato canônico
YYYY-[M]M-[D]D[( |T)[H]H:[M]M:[S]S[.DDDDDD]]
  • YYYY: ano de quatro dígitos
  • [M]M: mês de um ou dois dígitos.
  • [D]D: dia de um ou dois dígitos
  • ( |T): um espaço ou um separador "T".
  • [H]H: hora de um ou dois dígitos (valores válidos de 00 a 23)
  • [M]M: minutos de um ou dois dígitos (valores válidos de 00 a 59).
  • [S]S: segundos de um ou dois dígitos (valores válidos de 00 a 59).
  • [.DDDDDD]: até seis dígitos fracionários (precisão de microssegundo)

Tipo time

Nome Intervalo
TIME De 00:00:00 a 23:59:59,99999.

Um objeto TIME representa um horário, do modo ele é exibido em um relógio, independentemente de data e fuso horário específicos. Para representar um ponto absoluto no tempo, use um carimbo de data/hora.

Formato canônico
[H]H:[M]M:[S]S[.DDDDDD]
  • [H]H: hora de um ou dois dígitos (valores válidos de 00 a 23)
  • [M]M: minutos de um ou dois dígitos (valores válidos de 00 a 59).
  • [S]S: segundos de um ou dois dígitos (valores válidos de 00 a 59).
  • [.DDDDDD]: até seis dígitos fracionários (precisão de microssegundo)

Tipo timestamp

Nome Intervalo
TIMESTAMP De 0001-01-01 00:00:00 a 9999-12-31 23:59:59,999999 UTC

Um objeto TIMESTAMP representa um ponto absoluto no tempo, independentemente de qualquer fuso horário ou convenção, como horário de verão, com precisão de microssegundos.

  • Para representar uma data como ela aparece em uma calendário, use um objeto DATE.
  • Para representar um horário, do modo como ele aparece em um relógio, use um objeto TIME.
  • Para representar uma data e uma hora, do modo como aparecem em um calendário e um relógio, use um objeto DATETIME.
Formato canônico
YYYY-[M]M-[D]D[( |T)[H]H:[M]M:[S]S[.DDDDDD]][time zone]
  • YYYY: ano de quatro dígitos
  • [M]M: mês de um ou dois dígitos.
  • [D]D: dia de um ou dois dígitos
  • ( |T): um espaço ou um separador "T".
  • [H]H: hora de um ou dois dígitos (valores válidos de 00 a 23)
  • [M]M: minutos de um ou dois dígitos (valores válidos de 00 a 59).
  • [S]S: segundos de um ou dois dígitos (valores válidos de 00 a 59).
  • [.DDDDDD]: até seis dígitos fracionários (precisão de microssegundo)
  • [time zone]: string que representa o fuso horário. Quando um fuso horário não for especificado explicitamente, será utilizado o fuso horário padrão: UTC. Consulte a seção fusos horários para mais informações.

Fusos horários

Fusos horários são usados na análise ou formatação de carimbos de data/hora para exibição. O valor de carimbo de data/hora em si não armazena um fuso horário específico nem é alterado ao aplicar uma diferença de fuso horário.

Fusos horários são representados por strings em um destes dois formatos canônicos:

  • Diferença do Tempo Universal Coordenado (UTC) ou da letra Z para UTC
  • Nome do fuso horário proveniente do banco de dados tz

Diferença do Tempo Universal Coordenado (UTC)

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

Exemplos

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

Quando se usa esse formato, nenhum espaço é permitido entre o fuso horário e o resto do carimbo de data/hora.

2014-09-27 12:30:00.45-8:00
2014-09-27T12:30:00.45Z

Nome do fuso horário

continent/[region/]city

Os nomes dos fusos horários vêm do banco de dados tz. Para uma referência menos abrangente, porém mais simples, consulte a Lista de fusos horários do banco de dados tz na Wikipédia.

Exemplos

America/Los_Angeles
America/Argentina/Buenos_Aires

Quando se usa um nome de fuso horário, é necessário um espaço entre o nome e o resto do carimbo de data/hora.

2014-09-27 12:30:00.45 America/Los_Angeles

Observe que nem todos os nomes de fuso horário são intercambiáveis, mesmo se informarem a mesma hora durante uma determinada parte do ano. Por exemplo: America/Los_Angeles informa o mesmo horário que UTC-7:00 durante o horário de verão, mas também informa o mesmo horário que UTC-8:00 fora do horário de verão.

Se não houver especificação de fuso horário, será usado o valor padrão.

Segundos bissextos

Um timestamp é simplesmente uma diferença de 1970-01-01 00:00:00 UTC, supondo-se que haja exatamente 60 segundos por minuto. Os segundos bissextos não são representados como parte de um carimbo de data/hora armazenado.

Se a entrada contiver valores que usam ":60" no campo de segundos para representar um segundo bissexto, ele não será preservado na conversão para um valor de carimbo de data/hora. Em vez disso, o valor é interpretado como um carimbo de data/hora com ":00" no campo de segundos do minuto seguinte.

Os segundos bissextos não afetam os cálculos de timestamp. Todos os cálculos de timestamp são feitos com carimbos de data/hora no estilo Unix, que não refletem segundos bissextos. Só é possível perceber os segundos bissextos por meio de funções que medem o tempo do mundo real. Nessas funções, é possível pular ou repetir um segundo de timestamp quando há um segundo bissexto.

Tipo array

Nome Descrição
ARRAY Lista ordenada de zero ou mais elementos de qualquer tipo não ARRAY.

Um ARRAY é uma lista ordenada de zero ou mais elementos de valores não ARRAY. Não pode haver ARRAYs de ARRAYs. Consultas que produzam um ARRAY de ARRAYs retornam erro. Em vez disso, um STRUCT precisa ser inserido entre as ARRAYs usando a construção SELECT AS STRUCT.

Atualmente, o BigQuery tem estas duas limitações relacionadas aos elementos NULLs e ARRAYs:

  • O BigQuery acusará erro se o resultado da consulta tiver ARRAYs contendo elementos NULL, embora seja possível usar esses ARRAYs dentro da consulta.
  • O BigQuery converte o ARRAY NULL em ARRAY vazio no resultado da consulta, embora dentro da consulta os ARRAYs NULL e vazios sejam dois valores distintos.

Declaração de um tipo ARRAY

ARRAY<T>

Tipos ARRAY são declarados por meio de parênteses angulares (< e >). O tipo dos elementos de uma ARRAY pode ser aleatoriamente complexo, com a exceção de que uma ARRAY não pode conter diretamente outra ARRAY.

Exemplos

Declaração do tipo Significado
ARRAY<INT64> ARRAY simples de inteiros de 64 bits.
ARRAY<STRUCT<INT64, INT64>> Um ARRAY de STRUCTs contendo, cada, dois inteiros de 64 bits.
ARRAY<ARRAY<INT64>>
(Indisponível)
Esta é uma declaração de tipo inválida que está incluída aqui para o caso de você ter procurado uma ARRAY de vários níveis. ARRAYs não podem conter ARRAYs diretamente. Veja o próximo exemplo:
ARRAY<STRUCT<ARRAY<INT64>>> Um ARRAY de ARRAYS de inteiros de 64 bits. Observe que há um STRUCT entre os dois ARRAYs porque os ARRAYs não podem conter outros ARRAYs diretamente.

Tipo struct

Nome Descrição
STRUCT Contêiner de campos ordenados, cada um com um tipo (obrigatório) e um nome de campo (opcional).

Declaração de um tipo STRUCT

STRUCT<T>

Tipos STRUCT são declarados por meio do uso de parênteses angulares (< e >). O tipo dos elementos de um STRUCT pode ser aleatoriamente complexo.

Exemplos

Declaração do tipo Significado
STRUCT<INT64> STRUCT simples com um único campo de inteiro de 64 bits sem nome.
STRUCT<x STRUCT<y INT64, z INT64>> Um STRUCT com um STRUCT aninhado, nomeado x, dentro dele. O STRUCT x tem dois campos, y e z, ambos inteiros de 64 bits.
STRUCT<inner_array ARRAY<INT64>> Um STRUCT que contém uma ARRAY denominada inner_array que abrange elementos inteiros de 64 bits.

Construção de um STRUCT

Sintaxe de tupla

(expr1, expr2 [, ... ])

O tipo de saída é um STRUCT anônimo com campos anônimos, cujos tipos correspondem aos tipos das expressões de entrada. É preciso especificar pelo menos duas expressões. Caso contrário, não se distingue essa sintaxe de uma expressão envolvida por parênteses.

Exemplos

Sintaxe Tipo de saída Observações
(x, x+y) STRUCT<?,?> Se forem usados nomes de coluna (strings sem aspas), o tipo de dados do campo STRUCT será derivado do tipo de dados da coluna. Então, como x e y são colunas, os tipos de dados dos campos STRUCT são derivados dos tipos de coluna e do tipo de saída do operador de adição.

Essa sintaxe também pode ser usada com a comparação de STRUCT nas expressões de comparação usando-se chaves de várias partes, por exemplo, em uma cláusula WHERE:

WHERE (Key1,Key2) IN ( (12,34), (56,78) )

Sintaxe de struct sem especificação de tipo

STRUCT( expr1 [AS field_name] [, ... ])

É permitido duplicar nomes de campo. Os campos sem nome são considerados anônimos e não é possível referenciá-los pelo nome. Os valores de STRUCT podem ser NULL ou ter valores de campo NULL.

Exemplos

Sintaxe Tipo de saída
STRUCT(1,2,3) STRUCT<int64,int64,int64>
STRUCT() STRUCT<>
STRUCT('abc') STRUCT<string>
STRUCT(1, t.str_col) STRUCT<int64, str_col string>
STRUCT(1 AS a, 'abc' AS b) STRUCT<a int64, b string>
STRUCT(str_col AS abc) STRUCT<abc string>

Sintaxe de struct com tipo especificado

STRUCT<[field_name] field_type, ...>( expr1 [, ... ])

A sintaxe tipada permite construir STRUCTs com um tipo de dados STRUCT explícito. O tipo de saída é exatamente o field_type fornecido. A expressão de entrada é forçada para field_type se os dois tipos não forem iguais, e haverá um erro se os tipos não forem compatíveis. AS alias não é permitido nas expressões de entrada. O número de expressões precisa corresponder ao número de campos do tipo, e os tipos de expressão precisam ser coercíveis ou literais-coercíveis em relação aos tipos de campo.

Exemplos

Sintaxe Tipo de saída
STRUCT<int64>(5) STRUCT<int64>
STRUCT<date>("2011-05-05") STRUCT<date>
STRUCT<x int64, y string>(1, t.str_col) STRUCT<x int64, y string>
STRUCT<int64>(int_col) STRUCT<int64>
STRUCT<x int64>(5 AS x) Erro - sintaxe tipada não permite AS

Comparações limitadas de STRUCT

É possível fazer comparação direta de STRUCTs usando-se operadores de igualdade:

  • Igual (=)
  • Não igual (!= ou <>)
  • [NOT] IN

Observe, porém, que essas comparações de igualdade diretas comparam os campos do STRUCT em pares na ordem de ordinais, ignorando nomes de campo. Se você preferir comparar campos com nomes idênticos de um STRUCT, poderá comparar os campos individuais diretamente.

Tipo geography

Nome Descrição
GEOGRAPHY Uma coleção de pontos, linhas e polígonos, representados como um conjunto de pontos, ou um subconjunto da superfície da Terra.

O tipo GEOGRAPHY, baseado na especificação Simple Features (SFS, na sigla em inglês) da OGC, é uma coleção de pontos, linhas ou polígonos que formam uma disposição "simples" no elipsoide de referência WGS84 (ambos em inglês). Uma disposição simples é aquela em que nenhum ponto da superfície do WGS84 é contido por vários elementos da coleção. As autointerseções serão removidas automaticamente, se houver.

O tipo GEOGRAPHY é um argumento para uma função geográfica ou o resultado dela.