

 O Amazon Redshift não permitirá mais a criação de UDFs do Python a partir do Patch 198. As UDFs do Python existentes continuarão a funcionar normalmente até 30 de junho de 2026. Para ter mais informações, consulte a [publicação de blog ](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

# Consultar dados semiestruturados
<a name="query-super"></a>

Com o Amazon Redshift, é possível consultar e analisar dados semiestruturados, como JSON, Avro ou Ion, bem como dados estruturados. Dados semiestruturados referem-se a dados que têm um esquema flexível que permite estruturas hierárquicas ou agrupadas. As seções a seguir demonstram a consulta de dados semiestruturados usando o suporte do Amazon Redshift a formatos de dados abertos, o que permite que você extraia informações valiosas de estruturas de dados complexas.

O Amazon Redshift usa a linguagem PartiQL para oferecer acesso compatível com SQL a dados relacionais, semiestruturados e aninhados. 

O PartiQL opera com tipos dinâmicos. Esse método permite filtragem intuitiva, junção e agregação na combinação de conjuntos de dados estruturados, semiestruturados e aninhados. A sintaxe do PartiQL usa notação pontilhada e array subscript para navegação de caminho ao acessar dados aninhados. Ele também permite que os itens da cláusula FROM para iterar sobre arrays e usar para operações unnest. As seções a seguir descrevem os diferentes padrões de consulta que combinam o uso do tipo de dados SUPER com a navegação de caminho e matriz, desfazer aninhamento, transformar colunas em linhas ou junções. Para obter mais informações sobre a PartiQL, consulte [PartiQL: uma linguagem de consultas compatível com SQL para o Amazon Redshift](super-partiql.md).

## Navegação
<a name="navigation"></a>

O Amazon Redshift usa o PartiQL para habilitar a navegação em arrays e estruturas usando o colchete [...] e a notação de pontos, respectivamente. Além disso, você pode misturar navegação em estruturas usando a notação de pontos e arrays usando a notação de colchetes. Por exemplo, a instrução a seguir seleciona somente o terceiro elemento em uma matriz aninhada a um nível de profundidade em um objeto SUPER:

```
SELECT super_object.array[2];
         
 array
---------------
 third_element
```

Você pode usar a notação de ponto e colchetes ao realizar operações de dados, como filtrar, unir e agregar. Você pode usar essas notações em qualquer lugar em uma consulta na qual normalmente há referências de coluna. Por exemplo, a instrução a seguir seleciona o número de eventos com o tipo `UPDATED`. 

```
SELECT COUNT(*)
FROM test_json
WHERE all_data.data.pnr.events[0]."eventType" = 'UPDATED';
         
 eventType | count
-----------+-------
 "UPDATED" | 1
```

Para obter exemplos mais detalhados do uso da navegação PartiQL, consulte [Exemplos de uso de dados semiestruturados no Amazon Redshift](super-examples.md).

## Desaninhar consultas
<a name="unnest"></a>

Para consultas desaninhadas, o Amazon Redshift oferece duas maneiras de iterar em matrizes SUPER: a sintaxe PartiQL e a operação UNNEST na cláusula FROM. Ambos os métodos de desagrupamento geram a mesma saída. Para ter informações sobre a operação UNNEST, consulte [Cláusula FROM](r_FROM_clause30.md). Para obter exemplos de uso da operação UNNEST, consulte [Exemplos de UNNEST](r_FROM_clause-unnest-examples.md). 

O Amazon Redshift pode percorrer matrizes SUPER usando a sintaxe PartiQL na cláusula FROM de uma consulta. Com o exemplo anterior, o exemplo a seguir itera sobre os valores do atributo para `c_orders`.

```
SELECT orders.*, o FROM customer_orders orders, orders.c_orders o;
```

 A sintaxe PartiQL de desaninhamento usando o item da cláusula FROM `x (AS) y` significa que `y` itera sobre cada valor (SUPER) na expressão de matriz x. Nesse caso, `x` é uma expressão SUPER, e `y` é um alias para `x`.

O operando esquerdo também pode usar a notação de pontos e colchetes para navegação regular. No exemplo a seguir, `customer_orders_lineitem c` é a iteração sobre a tabela `customer_order_lineitem` de base, e `c.c_orders o` é a iteração sobre a matriz `c.c_orders`. Para iterar sobre o atributo `o_lineitems`, que é uma matriz dentro de uma matriz, você pode adicionar várias cláusulas, como:

```
SELECT c.*, o, l FROM customer_orders_lineitem c, c.c_orders o, o.o_lineitems l;
```

O Amazon Redshift também oferece suporte ao índice de matriz ao iterar sobre a matriz usando a palavra-chave AT. A cláusula `x AS y AT z` itera sobre a matriz `x` e gera o campo `z,`, que é o índice da matriz. O exemplo a seguir mostra como o índice da matriz funciona.

```
SELECT c_name,
       orders.o_orderkey AS orderkey,
       index AS orderkey_index
FROM customer_orders_lineitem c, c.c_orders AS orders AT index 
ORDER BY orderkey_index;

c_name             | orderkey | orderkey_index
-------------------+----------+----------------
Customer#000008251 | 3020007  |        0
Customer#000009452 | 4043971  |        0
  (2 rows)
```

Veja a seguir um exemplo de iteração sobre uma matriz escalar.

```
CREATE TABLE bar AS SELECT json_parse('{"scalar_array": [1, 2.3, 45000000]}') AS data;

SELECT element, index FROM bar AS b, b.data.scalar_array AS element AT index;

 index | element
-------+----------
     0 | 1
     1 | 2.3
     2 | 45000000
(3 rows)
```

O exemplo a seguir itera sobre uma matriz de vários níveis. O exemplo usa várias cláusulas unnest para iterar nas matrizes mais internas. O AS da matriz `f.multi_level_array` itera sobre `multi_level_array`. O elemento AS da matriz é a iteração sobre as matrizes dentro de `multi_level_array`.

```
CREATE TABLE foo AS SELECT json_parse('[[1.1, 1.2], [2.1, 2.2], [3.1, 3.2]]') AS multi_level_array;

SELECT array, element FROM foo AS f, f.multi_level_array AS array, array AS element;

 element | array
---------+---------
 1.1     | [1.1,1.2]
 1.2     | [1.1,1.2]
 2.1     | [2.1,2.2] 
 2.2     | [2.1,2.2]
 3.1     | [3.1,3.2] 
 3.2     | [3.1,3.2] 
(6 rows)
```

Para obter mais informações sobre a cláusula FROM, consulte [Cláusula FROM](r_FROM_clause30.md). Para obter mais exemplos de desaninhamento de consultas SUPER, consulte [Exemplos de uso de dados semiestruturados no Amazon Redshift](super-examples.md).

## Transformar colunas em linhas de objetos
<a name="unpivoting"></a>

Para transformar colunas em linhas de objetos, o Amazon Redshift usa a sintaxe PartiQL para iterar sobre objetos SUPER. Ele faz isso usando a cláusula FROM de uma consulta junto com a palavra-chave UNPIVOT. No exemplo a seguir, a expressão é o objeto `c.c_orders[0]`. A consulta de exemplo itera sobre cada atributo exibido pelo objeto.

```
SELECT attr as attribute_name, json_typeof(val) as value_type 
FROM customer_orders_lineitem c, UNPIVOT c.c_orders[0] AS val AT attr 
WHERE c_custkey = 9451;

 attribute_name  | value_type
-----------------+------------
 o_orderstatus   | string
 o_clerk         | string
 o_lineitems     | array
 o_orderdate     | string
 o_shippriority  | number
 o_totalprice    | number
 o_orderkey      | number
 o_comment       | string
 o_orderpriority | string
(9 rows)
```

Assim como no desaninhamento, a sintaxe da transformação de coluna em linhas é uma extensão da cláusula FROM. A diferença é que a sintaxe da transformação de colunas em linhas usa a palavra-chave UNPIVOT para indicar que está iterando sobre um objeto em vez de uma matriz. Ele usa AS `value_alias` para iteração sobre todos os valores dentro de um objeto e usa o AT `attribute_alias` para iterar sobre todos os atributos. Considere a seguinte sintaxe:

```
UNPIVOT expression AS value_alias [ AT attribute_alias ]
```

O Amazon Redshift aceita o uso de desagregação de objetos e desaninhamento de matriz em uma única cláusula FROM da seguinte forma:

```
SELECT attr as attribute_name, val as object_value
FROM customer_orders_lineitem c, c.c_orders AS o, UNPIVOT o AS val AT attr 
WHERE c_custkey = 9451;
```

Ao usar a transformação de coluna em linha de objetos, o Amazon Redshift não oferece suporte a transformação de coluna em linha correlacionada. Especificamente, suponha que você tenha um caso em que há vários exemplos de transformação de coluna em linha em diferentes níveis de consulta e transformação de coluna em linha interna faz referência à externa. O Amazon Redshift não oferece suporte a este tipo de transformações múltiplas de coluna em linha.

Para obter mais informações sobre a cláusula FROM, consulte [Cláusula FROM](r_FROM_clause30.md). Para obter exemplos de uso da rotação com o tipo SUPER, consulte [Exemplos de uso de dados semiestruturados no Amazon Redshift](super-examples.md).

## Digitação dinâmica
<a name="dynamic-typing-lax-processing"></a>

A digitação dinâmica não requer fundição explícita de dados que são extraídos dos caminhos de ponto e colchetes. O Amazon Redshift usa a digitação dinâmica para processar dados SUPER sem esquema sem a necessidade de declarar os tipos de dados antes de usá-los em sua consulta. A digitação dinâmica usa os resultados da navegação em colunas de dados SUPER sem ter que convertê-las explicitamente nos tipos do Amazon Redshift. A digitação dinâmica é mais útil em junções e cláusulas GROUP BY. O exemplo a seguir usa uma instrução SELECT que não requer conversão explícita das expressões de ponto e colchetes para os tipos habituais do Amazon Redshift. Para obter informações sobre a compatibilidade e conversão de tipos, consulte [Compatibilidade e conversão dos tipos](c_Supported_data_types.md#r_Type_conversion).

Considere o exemplo a seguir, que procura linhas em que o status de um pedido é `shipped`:

```
SELECT c_orders[0].o_orderkey
FROM customer_orders_lineitem
WHERE c_orders[0].o_orderstatus = 'shipped';
```

O sinal de igualdade nesta consulta de exemplo é avaliado como `true` quando o valor de c\$1orders[0].o\$1orderstatus é a string ‘shipped’. Em todos os demais casos, o sinal de igualdade é avaliado como `false`, incluindo os casos em que os argumentos da igualdade são diferentes tipos. Por exemplo, se o status do pedido for um número inteiro, sua linha não será selecionada.

### Digitação dinâmica e estática
<a name="dynamic-typing-lax-processing-dynamic-and-static"></a>

Sem usar a digitação dinâmica, você não pode determinar se c\$1orders [0] .o\$1orderstatus é uma string, um inteiro ou uma estrutura. Você só pode determinar que c\$1orders [0] .o\$1orderstatus é um tipo de dados SUPER, que pode ser um escalar, um array ou uma estrutura do Amazon Redshift. O tipo estático de c\$1orders [0] .o\$1orderstatus é um tipo de dados SUPER. Convencionalmente, um tipo é implicitamente um tipo estático no SQL.

O Amazon Redshift usa a digitação dinâmica para o processamento de dados sem esquema. Quando a consulta avalia os dados, c\$1orders [0] .o\$1orderstatus acaba por ser um tipo específico. Por exemplo, avaliar c\$1orders [0] .o\$1orderstatus no primeiro registro de customer\$1orders\$1lineitem pode resultar em um inteiro. A avaliação no segundo registro pode resultar em uma string. Estes são os tipos dinâmicos da expressão.

Ao usar um operador ou função SQL com expressões de ponto e colchetes que têm tipos dinâmicos, o Amazon Redshift produz resultados semelhantes ao uso do operador ou função SQL padrão com os respectivos tipos estáticos. Neste exemplo, quando o tipo dinâmico da expressão de caminho é uma string, a comparação com a string 'P' é significativa. Sempre que o tipo dinâmico de c\$1orders [0] .o\$1orderstatus é qualquer outro tipo de dados exceto ser uma string, a igualdade retorna false. Outras funções retornam null quando argumentos digitados incorretamente são usados.

O seguinte exemplo grava a consulta anterior com digitação estática:

```
SELECT c_custkey
FROM customer_orders_lineitem
WHERE CASE WHEN JSON_TYPEOF(c_orders[0].o_orderstatus) = 'string'
           THEN c_orders[0].o_orderstatus::VARCHAR = 'P'
           ELSE FALSE END;
```

Observe a seguinte distinção entre predicados de igualdade e predicados de comparação. No exemplo anterior, se você substituir o predicado de igualdade por um predicado menor que ou igual, a semântica produzirá null em vez de false.

```
SELECT c_orders[0]. o_orderkey
FROM customer_orders_lineitem
WHERE c_orders[0].o_orderstatus <= 'P';
```

Neste exemplo, se c\$1orders [0] .o\$1orderstatus for uma string, o Amazon Redshift retornará true se for alfabeticamente igual ou menor que 'P'. O Amazon Redshift retornará false se for alfabeticamente maior que 'P'. No entanto, se c\$1orders [0] .o\$1orderstatus não for uma string, o Amazon Redshift retornará null, pois o Amazon Redshift não pode comparar valores de tipos diferentes, conforme mostrado na consulta a seguir:

```
SELECT c_custkey
FROM customer_orders_lineitem
WHERE CASE WHEN JSON_TYPEOF(c_orders[0].o_orderstatus) = 'string'
           THEN c_orders[0].o_orderstatus::VARCHAR <= 'P'
           ELSE NULL END;
```

A digitação dinâmica não exclui de comparações de tipos que são minimamente comparáveis. Por exemplo, você pode converter os tipos escalares CHAR e VARCHAR do Amazon Redshift para SUPER. Eles são comparáveis como strings, inclusive ignorando caracteres de espaço em branco à direita semelhantes aos tipos CHAR e VARCHAR do Amazon Redshift. Da mesma forma, números inteiros, decimais e valores de ponto flutuante são comparáveis como valores SUPER. Especificamente para colunas decimais, cada valor também pode ter uma escala diferente. O Amazon Redshift ainda os considera como tipos dinâmicos.

O Amazon Redshift também oferece suporte à igualdade em objetos e arrays que são avaliados como profundos iguais, como avaliar profundamente em objetos ou arrays e comparar todos os atributos. Use profundo igual com cautela, porque o processo de realização de igual profundo pode ser demorado.

### Usar a digitação dinâmica para junções
<a name="dynamic-typing-lax-processing-joins"></a>

Para junções, a digitação dinâmica corresponde automaticamente aos valores com diferentes tipos dinâmicos sem executar uma longa análise CASE WHEN para descobrir quais tipos de dados podem aparecer. Por exemplo, suponha que sua organização alterou o formato que estava usando para chaves de peça ao longo do tempo.

As chaves iniciais de parte inteira emitidas são substituídas por chaves de partes de string, como 'A55', e posteriormente substituídas por chaves de partes de matriz, como ['X', 10] combinando uma string e um número. O Amazon Redshift não precisa executar uma longa análise de caso sobre chaves de peça e pode usar joins como mostrado no exemplo a seguir.

```
SELECT c.c_name
    ,l.l_extendedprice
    ,l.l_discount
FROM customer_orders_lineitem c
    ,c.c_orders o
    ,o.o_lineitems l
    ,supplier_partsupp s
    ,s.s_partsupps ps
WHERE l.l_partkey = ps.ps_partkey
AND c.c_nationkey = s.s_nationkey
ORDER BY c.c_name;
```

O exemplo a seguir mostra quão complexa e ineficiente a mesma consulta pode ser sem usar a digitação dinâmica:

```
SELECT c.c_name
    ,l.l_extendedprice
    ,l.l_discount
FROM customer_orders_lineitem c
    ,c.c_orders o
    ,o.o_lineitems l
    ,supplier_partsupp s
    ,s.s_partsupps ps
WHERE CASE WHEN IS_INTEGER(l.l_partkey) AND IS_INTEGER(ps.ps_partkey)
           THEN l.l_partkey::integer = ps.ps_partkey::integer
           WHEN IS_VARCHAR(l.l_partkey) AND IS_VARCHAR(ps.ps_partkey)
           THEN l.l_partkey::varchar = ps.ps_partkey::varchar
           WHEN IS_ARRAY(l.l_partkey) AND IS_ARRAY(ps.ps_partkey)
                AND IS_VARCHAR(l.l_partkey[0]) AND IS_VARCHAR(ps.ps_partkey[0])
                AND IS_INTEGER(l.l_partkey[1]) AND IS_INTEGER(ps.ps_partkey[1])
           THEN l.l_partkey[0]::varchar = ps.ps_partkey[0]::varchar
                AND l.l_partkey[1]::integer = ps.ps_partkey[1]::integer
           ELSE FALSE END
AND c.c_nationkey = s.s_nationkey
ORDER BY c.c_name;
```

## Consulta sem distinção entre maiúsculas e minúsculas
<a name="case-insensitive-super-queries"></a>

Você pode realizar comparações de strings de caracteres sem distinção entre maiúsculas e minúsculas em dados SUPER usando a função COLLATE ou definindo o agrupamento em nível de coluna ou de banco de dados. Para acessar mais informações sobre como definir o agrupamento na criação da tabela, consulte [CRIAR TABELA](r_CREATE_TABLE_NEW.md). Para acessar informações sobre o comportamento do agrupamento com operadores e funções de dados SUPER, consulte [Comportamento do agrupamento](operators-functions.md#collation-behavior).

O exemplo a seguir usa a função COLLATE em valores de string extraídos dos dados SUPER.

```
CREATE TABLE events (data SUPER);
INSERT INTO events VALUES (JSON_PARSE('{"status": "Active", "name": "Event1"}'));
INSERT INTO events VALUES (JSON_PARSE('{"status": "ACTIVE", "name": "Event2"}'));
INSERT INTO events VALUES (JSON_PARSE('{"status": "active", "name": "Event3"}'));

SELECT data.name FROM events 
WHERE COLLATE(data.status::VARCHAR, 'case_insensitive') = 'active';

 name
----------
 "Event1"
 "Event2"
 "Event3"
(3 rows)
```

Você também pode definir uma coluna SUPER com agrupamento sem distinção entre maiúsculas e minúsculas na criação da tabela. Nesse caso, as comparações de strings na coluna não diferenciam maiúsculas de minúsculas.

```
CREATE TABLE events_ci (data SUPER COLLATE CASE_INSENSITIVE);
INSERT INTO events_ci VALUES (JSON_PARSE('{"status": "Active"}'));
INSERT INTO events_ci VALUES (JSON_PARSE('{"status": "ACTIVE"}'));

SELECT * FROM events_ci WHERE data.status::VARCHAR = 'active';

 data
-----------------------
 {"status":"Active"}
 {"status":"ACTIVE"}
(2 rows)
```

## Semântica lax
<a name="lax-semantics"></a>

Por padrão, as operações de navegação em valores SUPER retornam null em vez de retornar um erro quando a navegação é inválida. A navegação do objeto é inválida se o valor SUPER não for um objeto ou se o valor SUPER for um objeto, mas não contiver o nome do atributo usado na consulta. Por exemplo, a consulta a seguir acessa um nome de atributo inválido na coluna de dados SUPER cdata:

```
SELECT c.c_orders.something FROM customer_orders_lineitem c;
```

Navegação de array retorna null se o valor SUPER não é um array ou o índice de array está fora dos limites. A consulta a seguir retorna null porque c\$1orders [1] [1] está fora dos limites. 

```
SELECT c.c_orders[1][1] FROM customer_orders_lineitem c;
```

A semântica lax é especialmente útil quando se usa a digitação dinâmica para lançar um valor SUPER. Transferir um valor SUPER para o tipo errado retorna null em vez de um erro se a conversão for inválida. Por exemplo, a consulta a seguir retorna null porque não pode converter o valor de sequência de caracteres 'Good' do atributo o\$1orderstatus de objeto para INTEGER. O Amazon Redshift retorna um erro para uma transmissão VARCHAR para INTEGER, mas não para uma transmissão SUPER.

```
SELECT c.c_orders.o_orderstatus::integer FROM customer_orders_lineitem c;
```

## Order by (Ordenar por)
<a name="order-by"></a>

O Amazon Redshift não define comparações SUPER entre valores com diferentes tipos dinâmicos. Um valor SUPER que é uma cadeia não é menor nem maior do que um valor SUPER que é um número. Para usar as cláusulas ORDER BY com colunas SUPER, o Amazon Redshift define um pedido total entre diferentes tipos a serem observados quando o Amazon Redshift classifica os valores SUPER usando as cláusulas ORDER BY. A ordem entre tipos dinâmicos é booleano, número, string, array, objeto.

Para obter um exemplo de uso de GROUP BY e ORDER BY em uma consulta SUPER, consulte [Filtrar dados semiestruturados](super-examples.md#super-examples-filter).