

 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/). 

# Cláusula FROM
<a name="r_FROM_clause30"></a>

A cláusula FROM em uma consulta lista as referências de tabela (tabelas, exibições e subconsultas) de onde os dados são selecionados. Se as referências de várias tabelas estiverem listadas, as tabelas devem ser juntadas, usando a sintaxe apropriada na cláusula FROM ou WHERE. Se nenhum critério de junção for especificado, o sistema processará a consulta como uma junção cruzada (produto cartesiano). 

**Topics**
+ [

## Sintaxe
](#r_FROM_clause30-synopsis)
+ [

## Parâmetros
](#r_FROM_clause30-parameters)
+ [

## Observações de uso
](#r_FROM_clause_usage_notes)
+ [

# Exemplos de PIVOT e UNPIVOT
](r_FROM_clause-pivot-unpivot-examples.md)
+ [

# Exemplos de JOIN
](r_Join_examples.md)
+ [

# Exemplos de UNNEST
](r_FROM_clause-unnest-examples.md)

## Sintaxe
<a name="r_FROM_clause30-synopsis"></a>

```
FROM table_reference [, ...]
```

onde *referência\$1tabela* é uma das seguintes: 

```
with_subquery_table_name [ table_alias ]
table_name [ * ] [ table_alias ]
( subquery ) [ table_alias ]
table_reference [ NATURAL ] join_type table_reference
   [ ON join_condition | USING ( join_column [, ...] ) ]
table_reference  join_type super_expression 
   [ ON join_condition ]
table_reference PIVOT ( 
   aggregate(expr) [ [ AS ] aggregate_alias ]
   FOR column_name IN ( expression [ AS ] in_alias [, ...] )
) [ table_alias ]
table_reference UNPIVOT [ INCLUDE NULLS | EXCLUDE NULLS ] ( 
   value_column_name 
   FOR name_column_name IN ( column_reference [ [ AS ]
   in_alias ] [, ...] )
) [ table_alias ]
UNPIVOT expression AS value_alias [ AT attribute_alias ]
( super_expression.attribute_name ) AS value_alias [ AT index_alias ]
UNNEST ( column_reference )
  [AS] table_alias ( unnested_column_name )
UNNEST ( column_reference ) WITH OFFSET
  [AS] table_alias ( unnested_column_name, [offset_column_name] )
```

O *table\$1alias* opcional pode ser usado para fornecer nomes temporários a tabelas e referências de tabelas complexas e, se desejado, também às respectivas colunas, da forma a seguir: 

```
[ AS ] alias [ ( column_alias [, ...] ) ]
```

## Parâmetros
<a name="r_FROM_clause30-parameters"></a>

 *com\$1subconsulta\$1nome\$1tabela*   
Tabela definida por uma subconsulta em [Cláusula WITH](r_WITH_clause.md). 

 *table\$1name*   
Nome de uma tabela ou exibição. 

 *alias*   
Nome alternativo temporário para uma tabela ou exibição. Um alias deve ser fornecido para uma tabela derivada de uma subconsulta. Em outras referências de tabela, os alias são opcionais. A palavra-chave AS é sempre opcional. Os alias de tabela oferecem um atalho conveniente para tabelas de identificação em outras partes de uma consulta, como a cláusula WHERE. Por exemplo:   

```
select * from sales s, listing l
where s.listid=l.listid
```

 *column\$1alias*   
Nome alternativo temporário para uma coluna em uma tabela ou exibição. 

 *subconsulta*   
Uma expressão de consulta que avalia para uma tabela. A tabela existe somente pela duração da consulta e geralmente recebe um nome ou *alias*. No entanto, um alias não é necessário. Você também pode definir nomes de colunas para tabelas que derivam de subconsultas. Nomear aliases de coluna é importante quando você deseja participar dos resultados de subconsultas a outras tabelas e quando você deseja selecionar ou restringir essas colunas em outro lugar da consulta.   
Uma subconsulta pode conter uma cláusula ORDER BY, mas essa cláusula poderá não ter qualquer efeito se uma cláusula LIMIT ou OFFSET também não estiver especificada. 

NATURAL   
Define um junção que usa automaticamente todos os pares de colunas com nomes idênticos em duas tabelas como colunas de junção. Nenhuma condição explícita de junção é necessária. Por exemplo, se as tabelas CATEGORY e EVENT apresentam colunas com nome CATID, um junção natural dessas tabelas é um junção pelas colunas CATID.   
Se uma junção NATURAL for especificada mas não existirem pares de colunas com o mesmo nome nas tabelas a serem juntadas, a junção padrão da consulta usada será a junção cruzada. 

 *join\$1type*   
Especifique um dos seguintes tipos de junção:   
+ [INNER] JOIN 
+ LEFT [OUTER] JOIN 
+ RIGHT [OUTER] JOIN 
+ FULL [OUTER] JOIN 
+ CROSS JOIN 
As junções cruzadas são junções não qualificadas; elas retornam o produto cartesiano das duas tabelas.   
As junções internas e externas são junções qualificadas. Elas podem ser qualificadas implicitamente (em junções naturais); com a sintaxe ON ou USING na cláusula FROM; ou com a condição de cláusula WHERE.   
Uma junção interna retorna somente linhas correspondentes, com base na condição de junção ou na lista de colunas de junção. Uma junção externa retorna todas as linhas que a junção interna equivalente deve retornar e linhas não correspondentes da tabela "esquerda", da tabela "direita" ou de ambas. A tabela esquerda é a primeira tabela listada, e a tabela direita é a segunda tabela listada. As linhas não correspondentes contêm valores NULL para preencher lacunas entre as colunas resultantes. 

ON *condição\$1junção*   
Tipo de especificação de junção em que as colunas a serem juntadas são exibidas como uma condição que acompanha a palavra-chave ON. Por exemplo:   

```
sales join listing
on sales.listid=listing.listid and sales.eventid=listing.eventid
```

USING ( *coluna\$1junção* [, ...] )   
Tipo de especificação de junção em que as colunas a serem juntadas estão listadas entre parênteses. Se várias colunas a serem juntadas forem especificadas, elas serão separadas por vírgulas. A palavra-chave USING deve preceder a lista. Por exemplo:   

```
sales join listing
using (listid,eventid)
```

PIVOT  
Alterna a saída de linhas para colunas, com a finalidade de representar dados tabulares em um formato de fácil leitura. A saída é representada horizontalmente em várias colunas. PIVOT é semelhante a uma consulta GROUP BY com uma agregação, usando uma expressão agregada para especificar um formato de saída. Porém, diferente de GROUP BY, os resultados são retornados em colunas em vez de linhas.  
Para obter exemplos que mostrem como consultar com PIVOT e UNPIVOT, consulte [Exemplos de PIVOT e UNPIVOT](r_FROM_clause-pivot-unpivot-examples.md).

UNPIVOT  
*Transformar colunas em linhas com UNPIVOT*: o operador transforma as colunas de resultados de uma tabela de entrada ou os resultados de uma consulta em linhas, para facilitar a leitura da saída. UNPIVOT combina os dados das colunas de entrada em duas colunas de resultado: uma coluna de nome e uma coluna de valor. A coluna name contém nomes de coluna da entrada, como entradas de linha. A coluna value contém valores das colunas de entrada, como resultados de uma agregação. Por exemplo, as contagens de itens em várias categorias.  
*Desagregar objetos com UNPIVOT (SUPER)*: é possível desagregar objetos; nesse caso, a *expressão* é uma expressão SUPER referente a outro item da cláusula FROM. Para obter mais informações, consulte [Transformar colunas em linhas de objetos](query-super.md#unpivoting). Também há exemplos que mostram como consultar dados semiestruturados, como dados formatados em JSON.

*super\$1expression*  
Uma expressão SUPER válida. O Amazon Redshift exibe uma linha para cada valor no atributo especificado. Para ter mais informações sobre o tipo de dado SUPER, consulte [Tipo SUPER](r_SUPER_type.md). Para ter mais informações sobre valores SUPER desaninhados, consulte [Desaninhar consultas](query-super.md#unnest).

*attribute\$1name*  
O nome de um atributo na expressão SUPER.

*index\$1alias*  
Alias para o índice que significa a posição do valor na expressão SUPER.

UNNEST  
Expande uma estrutura aninhada, normalmente uma matriz SUPER, em colunas que contêm os elementos não aninhados. Para ter mais informações sobre desagrupamento de dados SUPER, consulte [Consultar dados semiestruturados](query-super.md). Para obter exemplos, consulte [Exemplos de UNNEST](r_FROM_clause-unnest-examples.md). 

*unnested\$1column\$1name*  
O nome da coluna que contém os elementos não aninhados. 

UNNEST ... WITH OFFSET  
Adiciona uma coluna de deslocamento à saída não aninhada, e o deslocamento representa o índice baseado em zero de cada elemento na matriz. Essa variante é útil quando você deseja ver a posição dos elementos em uma matriz. Para ter mais informações sobre desagrupamento de dados SUPER, consulte [Consultar dados semiestruturados](query-super.md). Para obter exemplos, consulte [Exemplos de UNNEST](r_FROM_clause-unnest-examples.md). 

*offset\$1column\$1name*  
Um nome personalizado para a coluna de deslocamento que permite definir explicitamente como a coluna de índice aparecerá na saída. Esse parâmetro é opcional. Por padrão, o nome da coluna de deslocamento é `offset_col`. 

## Observações de uso
<a name="r_FROM_clause_usage_notes"></a>

Colunas de junção devem ter tipos de dados comparáveis. 

Uma junção NATURAL ou USING retém somente um de cada par de colunas de junção no conjunto de resultados intermediário. 

Uma junção com a sintaxe ON retém ambas as colunas de junção em seu conjunto de resultados intermediário. 

Consulte também [Cláusula WITH](r_WITH_clause.md). 

# Exemplos de PIVOT e UNPIVOT
<a name="r_FROM_clause-pivot-unpivot-examples"></a>

PIVOT e UNPIVOT são parâmetros na cláusula FROM que trocam a saída da consulta de linhas para colunas e colunas para linhas, respectivamente. Eles representam resultados de consultas tabulares em um formato fácil de ler. Os exemplos a seguir usam consultas e dados de teste para mostrar como usá-los.

Para obter mais informações sobre esses parâmetros, consulte [FROM clause](https://docs.aws.amazon.com/redshift/latest/dg/r_FROM_clause30.html).

## Exemplos de PIVOT
<a name="r_FROM_clause-pivot-examples"></a>

Configure a tabela e os dados de exemplo e use-os para executar as consultas de exemplo subsequentes.

```
CREATE TABLE part (
    partname varchar,
    manufacturer varchar,
    quality int,
    price decimal(12, 2)
);

INSERT INTO part VALUES ('prop', 'local parts co', 2, 10.00);
INSERT INTO part VALUES ('prop', 'big parts co', NULL, 9.00);
INSERT INTO part VALUES ('prop', 'small parts co', 1, 12.00);

INSERT INTO part VALUES ('rudder', 'local parts co', 1, 2.50);
INSERT INTO part VALUES ('rudder', 'big parts co', 2, 3.75);
INSERT INTO part VALUES ('rudder', 'small parts co', NULL, 1.90);

INSERT INTO part VALUES ('wing', 'local parts co', NULL, 7.50);
INSERT INTO part VALUES ('wing', 'big parts co', 1, 15.20);
INSERT INTO part VALUES ('wing', 'small parts co', NULL, 11.80);
```

PIVOT em `partname` com um agregação de `AVG` em `price`.

```
SELECT *
FROM (SELECT partname, price FROM part) PIVOT (
    AVG(price) FOR partname IN ('prop', 'rudder', 'wing')
);
```

A consulta resulta na saída a seguir.

```
  prop   |  rudder  |  wing
---------+----------+---------
 10.33   | 2.71     | 11.50
```

No exemplo anterior, os resultados são transformados em colunas. O exemplo a seguir mostra uma consulta `GROUP BY` que retorna os preços médios em linhas, em vez de em colunas.

```
SELECT partname, avg(price)
FROM (SELECT partname, price FROM part)
WHERE partname IN ('prop', 'rudder', 'wing')
GROUP BY partname;
```

A consulta resulta na saída a seguir.

```
 partname |  avg
----------+-------
 prop     | 10.33
 rudder   |  2.71
 wing     | 11.50
```

Um exemplo de `PIVOT` com `manufacturer` como uma coluna implícita.

```
SELECT *
FROM (SELECT quality, manufacturer FROM part) PIVOT (
    count(*) FOR quality IN (1, 2, NULL)
);
```

A consulta resulta na saída a seguir.

```
 manufacturer      | 1  | 2  | null
-------------------+----+----+------
 local parts co    | 1  | 1  |  1
 big parts co      | 1  | 1  |  1
 small parts co    | 1  | 0  |  2
```

 Colunas da tabela de entrada que não são referenciadas na definição `PIVOT` são adicionadas implicitamente à tabela de resultados. Este é o caso da coluna `manufacturer` no exemplo anterior. O exemplo também mostra que `NULL` é um valor válido para o operador `IN`. 

`PIVOT` no exemplo acima retorna informações semelhantes à consulta a seguir, que inclui `GROUP BY`. A diferença é que `PIVOT` retorna o valor `0` para a coluna `2` e o fabricante `small parts co`. A consulta `GROUP BY` não contém uma linha correspondente. Na maioria dos casos, `PIVOT` insere `NULL` se uma linha não tem dados de entrada para determinada coluna. Porém, o agregado de contagem não retorna `NULL` e `0` é o valor padrão.

```
SELECT manufacturer, quality, count(*)
FROM (SELECT quality, manufacturer FROM part)
WHERE quality IN (1, 2) OR quality IS NULL
GROUP BY manufacturer, quality
ORDER BY manufacturer;
```

A consulta resulta na saída a seguir.

```
 manufacturer        | quality | count
---------------------+---------+-------
 big parts co        |         |     1
 big parts co        |       2 |     1
 big parts co        |       1 |     1
 local parts co      |       2 |     1
 local parts co      |       1 |     1
 local parts co      |         |     1
 small parts co      |       1 |     1
 small parts co      |         |     2
```

 O operador PIVOT aceita aliases opcionais na expressão agregada e em cada valor para o operador `IN`. Use aliases para personalizar os nomes das colunas. Se não houver um alias agregado, somente os aliases da lista `IN` serão usados. Caso contrário, o alias agregado será anexado ao nome da coluna com um sublinhado para separar os nomes. 

```
SELECT *
FROM (SELECT quality, manufacturer FROM part) PIVOT (
    count(*) AS count FOR quality IN (1 AS high, 2 AS low, NULL AS na)
);
```

A consulta resulta na saída a seguir.

```
 manufacturer      | high_count  | low_count | na_count
-------------------+-------------+-----------+----------
 local parts co    |           1 |         1 |        1
 big parts co      |           1 |         1 |        1
 small parts co    |           1 |         0 |        2
```

Configure a tabela e os dados de exemplo a seguir e use-os para executar as consultas de exemplo subsequentes. Os dados representam datas de reserva para um grupo de hotéis.

```
CREATE TABLE bookings (
    booking_id int,
    hotel_code char(8),
    booking_date date,
    price decimal(12, 2)
);

INSERT INTO bookings VALUES (1, 'FOREST_L', '02/01/2023', 75.12);
INSERT INTO bookings VALUES (2, 'FOREST_L', '02/02/2023', 75.00);
INSERT INTO bookings VALUES (3, 'FOREST_L', '02/04/2023', 85.54);

INSERT INTO bookings VALUES (4, 'FOREST_L', '02/08/2023', 75.00);
INSERT INTO bookings VALUES (5, 'FOREST_L', '02/11/2023', 75.00);
INSERT INTO bookings VALUES (6, 'FOREST_L', '02/14/2023', 90.00);

INSERT INTO bookings VALUES (7, 'FOREST_L', '02/21/2023', 60.00);
INSERT INTO bookings VALUES (8, 'FOREST_L', '02/22/2023', 85.00);
INSERT INTO bookings VALUES (9, 'FOREST_L', '02/27/2023', 90.00);

INSERT INTO bookings VALUES (10, 'DESERT_S', '02/01/2023', 98.00);
INSERT INTO bookings VALUES (11, 'DESERT_S', '02/02/2023', 75.00);
INSERT INTO bookings VALUES (12, 'DESERT_S', '02/04/2023', 85.00);

INSERT INTO bookings VALUES (13, 'DESERT_S', '02/05/2023', 75.00);
INSERT INTO bookings VALUES (14, 'DESERT_S', '02/06/2023', 34.00);
INSERT INTO bookings VALUES (15, 'DESERT_S', '02/09/2023', 85.00);

INSERT INTO bookings VALUES (16, 'DESERT_S', '02/12/2023', 23.00);
INSERT INTO bookings VALUES (17, 'DESERT_S', '02/13/2023', 76.00);
INSERT INTO bookings VALUES (18, 'DESERT_S', '02/14/2023', 85.00);

INSERT INTO bookings VALUES (19, 'OCEAN_WV', '02/01/2023', 98.00);
INSERT INTO bookings VALUES (20, 'OCEAN_WV', '02/02/2023', 75.00);
INSERT INTO bookings VALUES (21, 'OCEAN_WV', '02/04/2023', 85.00);

INSERT INTO bookings VALUES (22, 'OCEAN_WV', '02/06/2023', 75.00);
INSERT INTO bookings VALUES (23, 'OCEAN_WV', '02/09/2023', 34.00);
INSERT INTO bookings VALUES (24, 'OCEAN_WV', '02/12/2023', 85.00);

INSERT INTO bookings VALUES (25, 'OCEAN_WV', '02/13/2023', 23.00);
INSERT INTO bookings VALUES (26, 'OCEAN_WV', '02/14/2023', 76.00);
INSERT INTO bookings VALUES (27, 'OCEAN_WV', '02/16/2023', 85.00);

INSERT INTO bookings VALUES (28, 'CITY_BLD', '02/01/2023', 98.00);
INSERT INTO bookings VALUES (29, 'CITY_BLD', '02/02/2023', 75.00);
INSERT INTO bookings VALUES (30, 'CITY_BLD', '02/04/2023', 85.00);

INSERT INTO bookings VALUES (31, 'CITY_BLD', '02/12/2023', 75.00);
INSERT INTO bookings VALUES (32, 'CITY_BLD', '02/13/2023', 34.00);
INSERT INTO bookings VALUES (33, 'CITY_BLD', '02/17/2023', 85.00);

INSERT INTO bookings VALUES (34, 'CITY_BLD', '02/22/2023', 23.00);
INSERT INTO bookings VALUES (35, 'CITY_BLD', '02/23/2023', 76.00);
INSERT INTO bookings VALUES (36, 'CITY_BLD', '02/24/2023', 85.00);
```

 Nesse exemplo de consulta, os registros de reservas são calculados para fornecer um total de cada semana. A data de término de cada semana se torna um nome de coluna.

```
SELECT * FROM
    (SELECT
       booking_id,
       (date_trunc('week', booking_date::date) + '5 days'::interval)::date as enddate,
       hotel_code AS "hotel code"
FROM bookings
) PIVOT (
    count(booking_id) FOR enddate IN ('2023-02-04','2023-02-11','2023-02-18') 
);
```

A consulta resulta na saída a seguir.

```
 hotel code | 2023-02-04  | 2023-02-11 | 2023-02-18
------------+-------------+------------+----------
 FOREST_L   |           3 |          2 |        1
 DESERT_S   |           4 |          3 |        2
 OCEAN_WV   |           3 |          3 |        3
 CITY_BLD   |           3 |          1 |        2
```

 O Amazon Redshift não é compatível com CROSSTAB para girar em várias colunas. No entanto, é possível alterar dados de linha em colunas, de forma semelhante a uma agregação com PIVOT, com uma consulta como a seguinte. Isso usa os mesmos dados de exemplo de reserva como no exemplo anterior.

```
SELECT 
  booking_date,
  MAX(CASE WHEN hotel_code = 'FOREST_L' THEN 'forest is booked' ELSE '' END) AS FOREST_L,
  MAX(CASE WHEN hotel_code = 'DESERT_S' THEN 'desert is booked' ELSE '' END) AS DESERT_S,
  MAX(CASE WHEN hotel_code = 'OCEAN_WV' THEN 'ocean is booked' ELSE '' END)  AS OCEAN_WV
FROM bookings
GROUP BY booking_date
ORDER BY booking_date asc;
```

O exemplo de consulta resulta em datas de reserva listadas ao lado de frases curtas que indicam quais hotéis estão reservados.

```
 booking_date  | forest_l         | desert_s         | ocean_wv
---------------+------------------+------------------+--------------------
 2023-02-01    | forest is booked | desert is booked |  ocean is booked
 2023-02-02    | forest is booked | desert is booked |  ocean is booked
 2023-02-04    | forest is booked | desert is booked |  ocean is booked
 2023-02-05    |                  | desert is booked |        
 2023-02-06    |                  | desert is booked |
```

Veja a seguir as observações de uso do `PIVOT`:
+ `PIVOT` pode ser aplicado a tabelas, subconsultas e expressões de tabela comuns (CTEs). `PIVOT` não pode ser aplicado a expressões `JOIN`, CTEs recursivos, `PIVOT` ou expressões `UNPIVOT`. Também não são compatíveis expressões `SUPER` não aninhadas e tabelas aninhadas do Redshift Spectrum.
+  `PIVOT` é compatível com funções agregadas `COUNT`, `SUM`, `MIN`, `MAX` e `AVG`. 
+ A expressão agregada `PIVOT` deve ser uma chamada de uma função agregada compatível. Expressões complexas na parte superior do agregado não são compatíveis. Os argumentos agregados não podem conter referências a tabelas diferentes da tabela de entrada do `PIVOT`. Referências correlacionadas a uma consulta principal também não são compatíveis. O argumento agregado pode conter subconsultas. Elas podem ser correlacionadas internamente ou na tabela de entrada `PIVOT`.
+  Os valores da lista `PIVOT IN` não podem ser referências de coluna ou subconsultas. Cada valor deve ser compatível com a referência de coluna `FOR`. 
+  Se os valores de lista `IN` não tiverem aliases, `PIVOT` gerará nomes de coluna padrão. Por valores `IN` constantes, como 'abc' ou 5, o nome da coluna padrão é a constante em si. Para qualquer expressão complexa, o nome da coluna é um nome padrão do Amazon Redshift, como `?column?`. 

## Exemplos de UNPIVOT
<a name="r_FROM_clause-unpivot-examples"></a>

Configure os dados de exemplo e use-os para executar os exemplos subsequentes.

```
CREATE TABLE count_by_color (quality varchar, red int, green int, blue int);

INSERT INTO count_by_color VALUES ('high', 15, 20, 7);
INSERT INTO count_by_color VALUES ('normal', 35, NULL, 40);
INSERT INTO count_by_color VALUES ('low', 10, 23, NULL);
```

`UNPIVOT` nas colunas de entrada vermelho, verde e azul.

```
SELECT *
FROM (SELECT red, green, blue FROM count_by_color) UNPIVOT (
    cnt FOR color IN (red, green, blue)
);
```

A consulta resulta na saída a seguir.

```
 color | cnt
-------+-----
 red   |  15
 red   |  35
 red   |  10
 green |  20
 green |  23
 blue  |   7
 blue  |  40
```

Por padrão, os valores `NULL` na coluna de entrada são ignorados e não produzem uma linha de resultado. 

O exemplo a seguir mostra `UNPIVOT` com `INCLUDE NULLS`.

```
SELECT *
FROM (
    SELECT red, green, blue
    FROM count_by_color
) UNPIVOT INCLUDE NULLS (
    cnt FOR color IN (red, green, blue)
);
```

A seguir está a saída resultante.

```
 color | cnt
-------+-----
 red   |  15
 red   |  35
 red   |  10
 green |  20
 green |
 green |  23
 blue  |   7
 blue  |  40
 blue  |
```

Se o parâmetro `INCLUDING NULLS` estiver definido, os valores de entrada `NULL` geram linhas de resultados.

`The following query shows UNPIVOT` com `quality` como uma coluna implícita.

```
SELECT *
FROM count_by_color UNPIVOT (
    cnt FOR color IN (red, green, blue)
);
```

A consulta resulta na saída a seguir.

```
 quality | color | cnt
---------+-------+-----
 high    | red   |  15
 normal  | red   |  35
 low     | red   |  10
 high    | green |  20
 low     | green |  23
 high    | blue  |   7
 normal  | blue  |  40
```

Colunas da tabela de entrada que não são referenciadas na definição `UNPIVOT` são adicionadas implicitamente à tabela de resultados. No exemplo, este é o caso da coluna `quality`.

O exemplo a seguir mostra `UNPIVOT` com aliases para valores na lista `IN`.

```
SELECT *
FROM count_by_color UNPIVOT (
    cnt FOR color IN (red AS r, green AS g, blue AS b)
);
```

A consulta anterior resulta na saída a seguir.

```
 quality | color | cnt
---------+-------+-----
 high    | r     |  15
 normal  | r     |  35
 low     | r     |  10
 high    | g     |  20
 low     | g     |  23
 high    | b     |   7
 normal  | b     |  40
```

O operador `UNPIVOT` aceita aliases opcionais em cada valor de lista `IN`. Cada alias fornece personalização dos dados em cada coluna `value`.

Veja a seguir as observações de uso do `UNPIVOT`.
+ `UNPIVOT` pode ser aplicado a tabelas, subconsultas e expressões de tabela comuns (CTEs). `UNPIVOT` não pode ser aplicado a expressões `JOIN`, CTEs recursivos, `PIVOT` ou expressões `UNPIVOT`. Também não são compatíveis expressões `SUPER` não aninhadas e tabelas aninhadas do Redshift Spectrum.
+ A lista `UNPIVOT IN` deve conter apenas referências de coluna da tabela de entrada. As colunas da lista `IN` devem ter um tipo comum com o qual todas sejam compatíveis. A coluna de valor `UNPIVOT` tem esse tipo comum. A coluna de nome `UNPIVOT` é do tipo `VARCHAR`.
+ Se um valor de lista `IN` não tiver um alias, `UNPIVOT` usará o nome da coluna como valor padrão.

# Exemplos de JOIN
<a name="r_Join_examples"></a>

Uma cláusula SQL JOIN é usada para combinar os dados de duas ou mais tabelas com base em campos comuns. Os resultados podem ou não mudar dependendo do método de junção especificado. Para obter mais informações sobre a sintaxe da cláusula JOIN, consulte [Parâmetros](r_FROM_clause30.md#r_FROM_clause30-parameters). 

O exemplo a seguir usa dados dos dados de amostra `TICKIT`. Para obter mais informações sobre o esquema de banco de dados, consulte [Banco de dados de exemplo](c_sampledb.md). Para saber como carregar dados de exemplo, consulte [Carregamento de dados](https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-sample-db.html) no *Guia de conceitos básicos do Amazon Redshift*.

A consulta a seguir é uma junção interna (sem a palavra-chave JOIN) entre a tabela LISTING e a tabela SALES, onde o LISTID da tabela LISTING está entre 1 e 5. Essa consulta corresponde aos valores da coluna LISTID na tabela LISTING (a tabela à esquerda) e na tabela SALES (tabela à direita). Os resultados mostram que LISTID 1, 4 e 5 correspondem aos critérios.

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing, sales
where listing.listid = sales.listid
and listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

A consulta a seguir é uma junção externa à esquerda. Junções externas esquerdas e direitas retêm valores de uma das tabelas de junção quando nenhuma correspondência é encontrada na outra tabela. As tabelas esquerdas e direitas são a primeiras e a segunda listadas na sintaxe. Os valores NULL são usados para preencher "lacunas" no conjunto de resultados. Essa consulta corresponde aos valores da coluna LISTID na tabela LISTING (a tabela à esquerda) e na tabela SALES (tabela à direita). Os resultados mostram que LISTIDs 2 e 3 não resultaram em nenhuma venda.

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing left outer join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     2 | NULL   | NULL
     3 | NULL   | NULL
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

A consulta a seguir é uma junção externa à direita. Essa consulta corresponde aos valores da coluna LISTID na tabela LISTING (a tabela à esquerda) e na tabela SALES (tabela à direita). Os resultados mostram que LISTIDs 1, 4 e 5 correspondem aos critérios.

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing right outer join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

A consulta a seguir é uma junção completa. As junções completas retêm valores das tabelas unidas quando nenhuma correspondência é encontrada na outra tabela. As tabelas esquerdas e direitas são a primeiras e a segunda listadas na sintaxe. Os valores NULL são usados para preencher "lacunas" no conjunto de resultados. Essa consulta corresponde aos valores da coluna LISTID na tabela LISTING (a tabela à esquerda) e na tabela SALES (tabela à direita). Os resultados mostram que LISTIDs 2 e 3 não resultaram em nenhuma venda.

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing full join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     2 | NULL   | NULL
     3 | NULL   | NULL
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

A consulta a seguir é uma junção completa. Essa consulta corresponde aos valores da coluna LISTID na tabela LISTING (a tabela à esquerda) e na tabela SALES (tabela à direita). Somente linhas que não resultam em vendas (LISTIDs 2 e 3) estão nos resultados.

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing full join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
and (listing.listid IS NULL or sales.listid IS NULL)
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     2 | NULL   | NULL
     3 | NULL   | NULL
```

O exemplo a seguir é uma junção interna com a cláusula ON. Nesse caso, as linhas NULL não são retornadas.

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from sales join listing
on sales.listid=listing.listid and sales.eventid=listing.eventid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

A consulta a seguir é uma junção cruzada ou junção cartesiana da tabela LISTING e da tabela SALES com um predicado para limitar os resultados. Essa consulta corresponde aos valores da coluna LISTID na tabela SALES e na tabela LISTING para LISTIDs 1, 2, 3, 4 e 5 em ambas as tabelas. Os resultados mostram que 20 linhas correspondem aos critérios.

```
select sales.listid as sales_listid, listing.listid as listing_listid
from sales cross join listing
where sales.listid between 1 and 5
and listing.listid between 1 and 5
order by 1,2;

sales_listid | listing_listid
-------------+---------------
1            | 1
1            | 2
1            | 3
1            | 4
1            | 5
4            | 1
4            | 2
4            | 3
4            | 4
4            | 5
5            | 1
5            | 1
5            | 2
5            | 2
5            | 3
5            | 3
5            | 4
5            | 4
5            | 5
5            | 5
```

O exemplo a seguir é uma junção natural entre duas tabelas. Nesse caso, as colunas listid, sellerid, eventid e dateid têm nomes e tipos de dados idênticos em ambas as tabelas e, portanto, são usadas como colunas de junção. Os resultados são limitados a cinco linhas.

```
select listid, sellerid, eventid, dateid, numtickets
from listing natural join sales
order by 1
limit 5;

listid | sellerid  | eventid | dateid | numtickets
-------+-----------+---------+--------+-----------
113    | 29704     | 4699    | 2075   | 22
115    | 39115     | 3513    | 2062   | 14
116    | 43314     | 8675    | 1910   | 28
118    | 6079      | 1611    | 1862   | 9
163    | 24880     | 8253    | 1888   | 14
```

O exemplo a seguir é uma junção entre duas tabelas com a cláusula USING. Nesse caso, as colunas listid e eventid são usadas como colunas de junção. Os resultados são limitados a cinco linhas.

```
select listid, listing.sellerid, eventid, listing.dateid, numtickets
from listing join sales
using (listid, eventid)
order by 1
limit 5;

listid | sellerid | eventid | dateid | numtickets
-------+----------+---------+--------+-----------
1      | 36861    | 7872    | 1850   | 10
4      | 8117     | 4337    | 1970   | 8
5      | 1616     | 8647    | 1963   | 4
5      | 1616     | 8647    | 1963   | 4
6      | 47402    | 8240    | 2053   | 18
```

A consulta a seguir é uma junção interna de duas subconsultas na cláusula FROM. A consulta encontra o número de ingressos vendidos e não vendidos para categorias diferentes de eventos (shows e apresentações). As subconsultas da cláusula FROM são subconsultas da *tabela*. Elas podem retornar várias colunas e linhas.

```
select catgroup1, sold, unsold
from
(select catgroup, sum(qtysold) as sold
from category c, event e, sales s
where c.catid = e.catid and e.eventid = s.eventid
group by catgroup) as a(catgroup1, sold)
join
(select catgroup, sum(numtickets)-sum(qtysold) as unsold
from category c, event e, sales s, listing l
where c.catid = e.catid and e.eventid = s.eventid
and s.listid = l.listid
group by catgroup) as b(catgroup2, unsold)

on a.catgroup1 = b.catgroup2
order by 1;

catgroup1 |  sold  | unsold
----------+--------+--------
Concerts  | 195444 |1067199
Shows     | 149905 | 817736
```

# Exemplos de UNNEST
<a name="r_FROM_clause-unnest-examples"></a>

UNNEST é um parâmetro na cláusula FROM que expande os dados aninhados em colunas que contêm os elementos não aninhados dos dados. Para ter informações sobre como desagrupar dados, consulte [Consultar dados semiestruturados](query-super.md).

A instrução a seguir cria e preenche a tabela `orders`, que contém uma coluna `products` com matrizes de IDs de produto. Os exemplos desta seção utilizam os dados de amostra nessa tabela. 

```
CREATE TABLE orders (
    order_id INT,
    products SUPER
);

-- Populate table
INSERT INTO orders VALUES
(1001, JSON_PARSE('[
        {
            "product_id": "P456",
            "name": "Monitor",
            "price": 299.99,
            "quantity": 1,
            "specs": {
                "size": "27 inch",
                "resolution": "4K"
            }
        }
    ]
')),
(1002, JSON_PARSE('
    [
        {
            "product_id": "P567",
            "name": "USB Cable",
            "price": 9.99,
            "quantity": 3
        },
        {
            "product_id": "P678",
            "name": "Headphones",
            "price": 159.99,
            "quantity": 1,
            "specs": {
                "type": "Wireless",
                "battery_life": "20 hours"
            }
        }
    ]
'));
```

Veja a seguir alguns exemplos de consulta desaninhada com os dados de amostra usando a sintaxe partiQL.

## Desagrupar uma matriz sem uma coluna OFFSET
<a name="r_FROM_clause-unnest-examples-no-offset"></a>

A consulta a seguir desagrupa as matrizes SUPER na coluna de produtos, e cada linha representa um item do pedido em `order_id`.

```
SELECT o.order_id, unnested_products.product
FROM orders o, UNNEST(o.products) AS unnested_products(product);

 order_id |                                                           product                                                           
----------+-----------------------------------------------------------------------------------------------------------------------------
     1001 | {"product_id":"P456","name":"Monitor","price":299.99,"quantity":1,"specs":{"size":"27 inch","resolution":"4K"}}
     1002 | {"product_id":"P567","name":"USB Cable","price":9.99,"quantity":3}
     1002 | {"product_id":"P678","name":"Headphones","price":159.99,"quantity":1,"specs":{"type":"Wireless","battery_life":"20 hours"}}
(3 rows)
```

A consulta a seguir localiza o produto mais caro em cada pedido.

```
SELECT o.order_id, MAX(unnested_products.product)
FROM orders o, UNNEST(o.products) AS unnested_products(product);

 order_id |                                                           product                                                           
----------+-----------------------------------------------------------------------------------------------------------------------------
     1001 | {"product_id":"P456","name":"Monitor","price":299.99,"quantity":1,"specs":{"size":"27 inch","resolution":"4K"}}
     1002 | {"product_id":"P678","name":"Headphones","price":159.99,"quantity":1,"specs":{"type":"Wireless","battery_life":"20 hours"}}
(2 rows)
```

## Desagrupar uma matriz com uma coluna OFFSET implícita
<a name="r_FROM_clause-unnest-examples-implicit-offset"></a>

A consulta a seguir usa o parâmetro `UNNEST ... WITH OFFSET` para mostrar a posição com base em zero de cada produto na respectiva matriz de pedidos.

```
SELECT o.order_id, up.product, up.offset_col
FROM orders o, UNNEST(o.products) WITH OFFSET AS up(product);

 order_id |                                                           product                                                           | offset_col 
----------+-----------------------------------------------------------------------------------------------------------------------------+------------
     1001 | {"product_id":"P456","name":"Monitor","price":299.99,"quantity":1,"specs":{"size":"27 inch","resolution":"4K"}}             |          0
     1002 | {"product_id":"P567","name":"USB Cable","price":9.99,"quantity":3}                                                          |          0
     1002 | {"product_id":"P678","name":"Headphones","price":159.99,"quantity":1,"specs":{"type":"Wireless","battery_life":"20 hours"}} |          1
(3 rows)
```

Como a declaração não especifica um alias para a coluna de deslocamento, o Amazon Redshift a denomina `offset_col` por padrão.

## Desagrupar uma matriz com uma coluna OFFSET explícita
<a name="r_FROM_clause-unnest-examples-explicit-offset"></a>

A consulta a seguir também usa o parâmetro `UNNEST ... WITH OFFSET` para mostrar os produtos nas respectivas matrizes de pedidos. A diferença nessa consulta em comparação com a consulta no exemplo anterior é que ela nomeia explicitamente a coluna de deslocamento com o alias `idx`.

```
SELECT o.order_id, up.product, up.idx
FROM orders o, UNNEST(o.products) WITH OFFSET AS up(product, idx);

 order_id |                                                           product                                                           | idx 
----------+-----------------------------------------------------------------------------------------------------------------------------+-----
     1001 | {"product_id":"P456","name":"Monitor","price":299.99,"quantity":1,"specs":{"size":"27 inch","resolution":"4K"}}             |   0
     1002 | {"product_id":"P567","name":"USB Cable","price":9.99,"quantity":3}                                                          |   0
     1002 | {"product_id":"P678","name":"Headphones","price":159.99,"quantity":1,"specs":{"type":"Wireless","battery_life":"20 hours"}} |   1
(3 rows)
```