Tipos de dados do SQL padrão

O BigQuery é compatível com tipos de dados simples, como números 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 dos 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 Pode aparecer, geralmente, em uma expressão após
GROUP BY, DISTINCT ou PARTITION BY.
No entanto, as expressões PARTITION BY não podem incluir
os tipos de ponto flutuante FLOAT e DOUBLE.
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 números inteiros, ponto flutuante e dados NUMERIC.

Tipo inteiro

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

Nome Tamanho do armazenamento Intervalo
INT64 8 bytes -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 nove dígitos decimais de escala. A precisão é a quantidade 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 Tamanho do armazenamento Descrição Intervalo
NUMERIC 16 bytes Valores decimais com 38 dígitos decimais de precisão e nove 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 Tamanho do armazenamento Descrição
FLOAT64 8 bytes 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 de pontos flutuantes especiais são agrupados dessa forma, incluindo o agrupamento feito por uma cláusula GROUP BY e 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 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 operam em 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 Descrição Intervalo
DATE Representa uma data do calendário lógico. 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 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 Descrição Intervalo
DATETIME Representa um ano, mês, dia, hora, minuto, segundo e subsegundo. 0001-01-01 00:00:00 a 9999-12-31 23:59:59.999999.

Um DATETIME representa um ponto no tempo. Cada DATETIME contém o seguinte:

  • ano
  • mês
  • dia
  • hora
  • minuto
  • segundo
  • subsegundo

Diferente dos carimbos de data/hora, um objeto DATETIME não se refere a uma instância absoluta no tempo. Em vez disso, é o tempo civil ou o tempo que um usuário veria em um relógio ou agenda.

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 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 (links 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.

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

Tipo time

Nome Descrição Intervalo
TIME Representa uma hora, independente de uma data específica. 00:00:00 a 23:59:59.999999.

Um tipo de dados TIME representa uma hora, independente de uma data específica.

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 Descrição Intervalo
TIMESTAMP Representa um ponto absoluto no tempo, com precisão de microssegundos. 0001-01-01 00:00:00 a 9999-12-31 23:59:59.999999 UTC.

Ele representa um ponto absoluto no tempo independente de qualquer fuso horário ou convenção, como o horário de verão.

TIMESTAMP fornece precisão de microssegundos.

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. Consulte a seção fusos horários para mais informações.

Os fusos horários são usados ao analisar ou formatar carimbos de data/hora para exibição. O próprio valor de carimbo de data/hora não armazena um fuso horário específico. Um carimbo de data/hora formatado em string pode incluir um fuso horário. Quando um fuso horário não é especificado explicitamente, utiliza-se o fuso horário padrão: UTC.

Fusos horários

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, na sigla em inglês)

Formato de diferença
(+|-)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 restante 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

Os nomes de fuso horário provêm do banco de dados tz (em inglês). Para ter uma referência menos abrangente e mais simples, veja a Lista de fusos horários do banco de dados tz (em inglês) na Wikipédia.

Formato
continent/[region/]city
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 restante 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 época do ano. Por exemplo, America/Los_Angeles mostra o mesmo horário de UTC-7:00 durante horários de verão e o mesmo horário de UTC-8:00 quando não está no horário de verão.

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

Segundos bissextos

Um carimbo de data/hora é 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 em 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 carimbo de data/hora. Todos esses cálculos 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 carimbo de data/hora 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

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

Formato

ARRAY<T>

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>>
Incompatível
Esta é uma declaração de tipo inválida que está incluída aqui para o caso de você ter procurado um 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 números inteiros de 64 bits. Perceba que há uma STRUCT entre os dois ARRAYs porque eles 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

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

Formato

STRUCT<T>

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 números inteiros de 64 bits.
STRUCT<inner_array ARRAY<INT64>> Um STRUCT que contém um ARRAY denominado inner_array que abrange elementos inteiros de 64 bits.

Construção de um STRUCT

Sintaxe de tupla

Formato
(expr1, expr2 [, ... ])

O tipo de saída é um STRUCT anônimo com campos anônimos, com tipos correspondentes 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 entre 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. Portanto, 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 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

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

Não é 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 especificação de tipo

Formato
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 será forçada a 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 usam 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, faça isso diretamente com os campos individuais.