

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# SELECT
<a name="sql-commands-select-spark"></a>

O comando SELECT retorna linhas de tabelas e funções definidas pelo usuário.

Os seguintes comandos, cláusulas e operadores de conjunto do SELECT SQL são compatíveis com o AWS Clean Rooms Spark SQL:

**Topics**
+ [SELECT list](sql-function-select-list-spark.md)
+ [Cláusula WITH](WITH_clause.md)
+ [Cláusula FROM](FROM_clause30.md)
+ [Cláusula JOIN](join-clause.md)
+ [Cláusula WHERE](WHERE_clause.md)
+ [Cláusula VALUES](VALUES.md)
+ [Cláusula GROUP BY](GROUP_BY_clause.md)
+ [Cláusula HAVING](HAVING_clause.md)
+ [Configurar operadores](UNION.md)
+ [Cláusula ORDER BY](ORDER_BY_clause.md)
+ [Exemplos de subconsulta](Subquery_examples.md)
+ [Subconsultas correlacionadas](correlated_subqueries.md)

A sintaxe, os argumentos e alguns exemplos vêm da Referência SQL do [Apache Spark](https://spark.apache.org/docs/latest/api/sql/).

# SELECT list
<a name="sql-function-select-list-spark"></a>

Os nomes SELECT list das colunas, funções e expressões que você deseja que a consulta retorne. A lista representa o resultado da consulta.

## Sintaxe
<a name="sql-function-select-list-syntax-spark"></a>

```
SELECT
[ DISTINCT ] | expression [ AS column_alias ] [, ...]
```

## Parâmetros
<a name="sql-function-select-list-parameters-spark"></a>

DISTINCT  
Opção que elimina linhas duplicadas do conjunto de resultados, com base em valores correspondentes em uma ou mais colunas.

*expression*  
Expressão formada por uma ou mais colunas que existem em tabelas referidas pela consulta. Uma expressão pode conter funções SQL. Por exemplo:

```
coalesce(dimension, 'stringifnull') AS column_alias
```

AS column\$1alias

Nome temporário da coluna que é usada no conjunto de resultados finais. A palavra-chave AS é opcional. Por exemplo:

```
coalesce(dimension, 'stringifnull') AS dimensioncomplete
```

Se você não especificar um alias para uma expressão que não for um nome de coluna simples, o resultado definido aplicará um nome padrão à coluna.

**nota**  
O alias é reconhecido logo após ser definido na lista de destino. Você não pode usar um alias em outras expressões definidas depois dele na mesma lista de destinos. 

# Cláusula WITH
<a name="WITH_clause"></a>

Uma cláusula WITH é uma cláusula opcional que precede a lista SELECT em uma consulta. A cláusula WITH define um ou mais *common\$1table\$1expressions*. Cada expressão de tabela comum (CTE) define uma tabela temporária, que é semelhante à definição de visualização. Você pode fazer referência a essas tabelas temporárias na cláusula FROM. Eles são usados apenas enquanto a consulta a que pertencem é executada. Cada CTE na cláusula WITH especifica um nome de tabela, uma lista opcional de nomes de coluna e uma expressão de consulta que é avaliada como uma tabela (uma instrução SELECT).

Subconsultas da cláusula WITH são uma forma eficiente de definir tabelas que podem ser usadas ao longo da execução de uma consulta. Em todos os casos, os mesmos resultados podem ser obtidos usando subconsultas no corpo principal da instrução SELECT, mas pode ser mais simples fazer leituras ou gravações de subconsultas da cláusula WITH. Sempre que possível, subconsultas da cláusula WITH por várias vezes referidas são aperfeiçoadas como subexpressões comuns, ou seja, é possível avaliar uma subconsulta WITH uma vez e reutilizar seus resultados. (Observe que subexpressões comuns não estão limitadas àquelas definidas na cláusula WITH.)

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

```
[ WITH common_table_expression [, common_table_expression , ...] ]
```

onde *common\$1table\$1expression* pode ser não recursivo. Segue-se a forma não recursiva: 

```
CTE_table_name AS ( query )
```

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

 *common\$1table\$1expression*   
Define uma tabela temporária que você pode fazer referência no [Cláusula FROM](FROM_clause30.md) e é usado somente durante a execução da consulta a qual pertence. 

 *CTE\$1table\$1name*   
Um nome exclusivo para uma tabela temporária que define os resultados da subconsulta de cláusula WITH. Você não pode usar nomes duplicados em uma única cláusula WITH. Cada subconsulta deve ter um nome de tabela que pode mencionado em [Cláusula FROM](FROM_clause30.md).

 *query*   
 Qualquer consulta SELECT que AWS Clean Rooms ofereça suporte. Consulte [SELECT](sql-commands-select-spark.md). 

## Observações de uso
<a name="WITH_clause-usage-notes"></a>

Você pode usar uma cláusula WITH na seguinte instrução SQL: 
+ SELECIONAR, COM, UNIR, UNIR TUDO, INTERSETAR, INTERSETAR TUDO, EXCETO OU EXCETO TUDO 

Se a cláusula FROM de uma consulta que contém a cláusula WITH não fizer referência a qualquer das tabelas definidas pela cláusula WITH, a cláusula WITH será ignorada e a consulta será executada como normal.

Uma tabela definida por uma subconsulta de cláusula WITH somente pode ser referida no escopo da consulta SELECT iniciada pela cláusula WITH. Por exemplo, você pode fazer referência a essa tabela na cláusula FROM da subconsulta na lista SELECT, na cláusula WHERE ou na cláusula HAVING. Você não pode usar a cláusula WITH em uma subconsulta e fazer referência à sua tabela na cláusula FROM da consulta principal ou de outra subconsulta. Este padrão de consulta resulta em uma mensagem de erro do formulário `relation table_name doesn't exist` para a tabela da cláusula WITH.

Você não pode especificar outra cláusula WITH em uma subconsulta de cláusula WITH.

Você não pode fazer referência antecipada a tabelas definidas por subconsultas da cláusula WITH. Por exemplo, a consulta a seguir retorna um erro devido à referência antecipada para a tabela W2 na definição da tabela W1: 

```
with w1 as (select * from w2), w2 as (select * from w1)
select * from sales;
ERROR:  relation "w2" does not exist
```

## Exemplos
<a name="WITH_clause-examples"></a>

O exemplo a seguir mostra o caso mais simples possível de uma consulta que contém uma cláusula WITH. A consulta WITH com o nome VENUECOPY seleciona todas as linhas da tabela VENUE. Por sua vez, a consulta principal seleciona todas as linhas de VENUECOPY. A tabela VENUECOPY existe somente durante a consulta. 

```
with venuecopy as (select * from venue)
select * from venuecopy order by 1 limit 10;
```

```
 venueid |         venuename          |    venuecity    | venuestate | venueseats
---------+----------------------------+-----------------+------------+------------
1 | Toyota Park                | Bridgeview      | IL         |          0
2 | Columbus Crew Stadium      | Columbus        | OH         |          0
3 | RFK Stadium                | Washington      | DC         |          0
4 | CommunityAmerica Ballpark  | Kansas City     | KS         |          0
5 | Gillette Stadium           | Foxborough      | MA         |      68756
6 | New York Giants Stadium    | East Rutherford | NJ         |      80242
7 | BMO Field                  | Toronto         | ON         |          0
8 | The Home Depot Center      | Carson          | CA         |          0
9 | Dick's Sporting Goods Park | Commerce City   | CO         |          0
v     10 | Pizza Hut Park             | Frisco          | TX         |          0
(10 rows)
```

O exemplo a seguir mostra uma cláusula WITH que produz duas tabelas, chamadas VENUE\$1SALES e TOP\$1VENUES. A segunda tabela de consulta WITH seleciona a partir da primeira. Por sua vez, a cláusula WHERE do bloco principal de consulta contém um subconsulta que restringe a tabela TOP\$1VENUES. 

```
with venue_sales as
(select venuename, venuecity, sum(pricepaid) as venuename_sales
from sales, venue, event
where venue.venueid=event.venueid and event.eventid=sales.eventid
group by venuename, venuecity),

top_venues as
(select venuename
from venue_sales
where venuename_sales > 800000)

select venuename, venuecity, venuestate,
sum(qtysold) as venue_qty,
sum(pricepaid) as venue_sales
from sales, venue, event
where venue.venueid=event.venueid and event.eventid=sales.eventid
and venuename in(select venuename from top_venues)
group by venuename, venuecity, venuestate
order by venuename;
```

```
        venuename       |   venuecity   | venuestate | venue_qty | venue_sales
------------------------+---------------+------------+-----------+-------------
August Wilson Theatre   | New York City | NY         |      3187 |  1032156.00
Biltmore Theatre        | New York City | NY         |      2629 |   828981.00
Charles Playhouse       | Boston        | MA         |      2502 |   857031.00
Ethel Barrymore Theatre | New York City | NY         |      2828 |   891172.00
Eugene O'Neill Theatre  | New York City | NY         |      2488 |   828950.00
Greek Theatre           | Los Angeles   | CA         |      2445 |   838918.00
Helen Hayes Theatre     | New York City | NY         |      2948 |   978765.00
Hilton Theatre          | New York City | NY         |      2999 |   885686.00
Imperial Theatre        | New York City | NY         |      2702 |   877993.00
Lunt-Fontanne Theatre   | New York City | NY         |      3326 |  1115182.00
Majestic Theatre        | New York City | NY         |      2549 |   894275.00
Nederlander Theatre     | New York City | NY         |      2934 |   936312.00
Pasadena Playhouse      | Pasadena      | CA         |      2739 |   820435.00
Winter Garden Theatre   | New York City | NY         |      2838 |   939257.00
(14 rows)
```

Os dois exemplos a seguir demonstram as regras para o escopo de referências de tabela com base subconsultas da cláusula WITH. A primeira consulta é executada, mas a segunda falha com um erro esperado. A primeira consulta tem a subconsulta de cláusula WITH na lista SELECT da consulta principal. A tabela definida pela cláusula WITH (HOLIDAYS) é referida na cláusula FROM da subconsulta na lista SELECT: 

```
select caldate, sum(pricepaid) as daysales,
(with holidays as (select * from date where holiday ='t')
select sum(pricepaid)
from sales join holidays on sales.dateid=holidays.dateid
where caldate='2008-12-25') as dec25sales
from sales join date on sales.dateid=date.dateid
where caldate in('2008-12-25','2008-12-31')
group by caldate
order by caldate;

caldate   | daysales | dec25sales
-----------+----------+------------
2008-12-25 | 70402.00 |   70402.00
2008-12-31 | 12678.00 |   70402.00
(2 rows)
```

A segunda consulta falha porque tenta fazer referência à tabela HOLIDAYS na consulta principal, assim como na subconsulta da lista SELECT. As referências principais da consulta estão fora do escopo. 

```
select caldate, sum(pricepaid) as daysales,
(with holidays as (select * from date where holiday ='t')
select sum(pricepaid)
from sales join holidays on sales.dateid=holidays.dateid
where caldate='2008-12-25') as dec25sales
from sales join holidays on sales.dateid=holidays.dateid
where caldate in('2008-12-25','2008-12-31')
group by caldate
order by caldate;

ERROR:  relation "holidays" does not exist
```

# Cláusula FROM
<a name="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](#FROM_clause30-synopsis)
+ [Parâmetros](#FROM_clause30-parameters)
+ [Observações de uso](#FROM_clause_usage_notes)

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

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

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

```
with_subquery_table_name | table_name | ( subquery ) [ [ AS ] alias ]
table_reference [ NATURAL ] join_type table_reference [ USING ( join_column [, ...] ) ]
table_reference [ INNER ] join_type table_reference ON expr
```

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

 *com\$1subconsulta\$1nome\$1tabela*   
Tabela definida por uma subconsulta em [Cláusula WITH](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
```
Se você definir um alias de tabela definido, o alias deverá ser usado para referenciar essa tabela na consulta.   
Por exemplo, se a consulta for `SELECT "tbl"."col" FROM "tbl" AS "t"`, a consulta falhará porque o nome da tabela está basicamente substituído agora. Uma consulta válida nesse caso seria `SELECT "t"."col" FROM "tbl" AS "t"`.

 *alias\$1coluna*   
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)
```

## Observações de uso
<a name="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](WITH_clause.md). 

# Cláusula JOIN
<a name="join-clause"></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. Junções externas esquerdas e direitas retêm valores de uma das tabelas de junção quando nenhuma correspondência é encontrada na outra tabela. 

A combinação do tipo JOIN e da condição de junção determina quais linhas são incluídas no conjunto de resultados final. As cláusulas SELECT e WHERE então controlam quais colunas são retornadas e como as linhas são filtradas. Compreender os diferentes tipos de JOIN e como usá-los de forma eficaz é uma habilidade crucial em SQL, pois permite combinar dados de várias tabelas de forma flexível e poderosa.

## Sintaxe
<a name="join-clause-syntax"></a>

```
SELECT column1, column2, ..., columnn
FROM table1
join_type table2
ON table1.column = table2.column;
```

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

 *SELECIONE coluna1, coluna2,..., coluna N*   
As colunas que você deseja incluir no conjunto de resultados. Você pode selecionar colunas de uma ou de ambas as tabelas envolvidas no JOIN. 

 *DA tabela 1*   
A primeira tabela (esquerda) na operação JOIN.

 *[JUNÇÃO \$1 JUNÇÃO INTERNA \$1 JUNÇÃO ESQUERDA [EXTERNA] \$1 JUNÇÃO DIREITA [EXTERNA] \$1 JUNÇÃO COMPLETA [EXTERNA]] tabela 2:*   
O tipo de JOIN a ser executado. JOIN ou INNER JOIN retorna somente as linhas com valores correspondentes em ambas as tabelas.   
LEFT [OUTER] JOIN retorna todas as linhas da tabela à esquerda, com as linhas correspondentes da tabela à direita.   
RIGHT [OUTER] JOIN retorna todas as linhas da tabela à direita, com as linhas correspondentes da tabela esquerda.   
FULL [OUTER] JOIN retorna todas as linhas das duas tabelas, independentemente de haver uma correspondência ou não.   
CROSS JOIN cria um produto cartesiano das linhas das duas tabelas.

 *NA tabela1.coluna = tabela2.coluna*   
A condição de junção, que especifica como as linhas nas duas tabelas são correspondidas. A condição de junção pode ser baseada em uma ou mais colunas.

 *Condição WHERE:*   
Uma cláusula opcional que pode ser usada para filtrar ainda mais o conjunto de resultados, com base em uma condição especificada. 

## Exemplo
<a name="Join_examples"></a>

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
```

# Tipos de união
<a name="join-types"></a>

## INNER
<a name="inner-join"></a>

Esse é o tipo de junção padrão. Retorna as linhas que têm valores correspondentes nas duas referências da tabela. 

O INNER JOIN é o tipo mais comum de junção usado em SQL. É uma forma poderosa de combinar dados de várias tabelas com base em uma coluna comum ou conjunto de colunas. 

**Sintaxe:**

```
SELECT column1, column2, ..., columnn
FROM table1
INNER JOIN table2
ON table1.column = table2.column;
```

A consulta a seguir retornará todas as linhas em que há um valor de customer\$1id correspondente entre as tabelas de clientes e pedidos. O conjunto de resultados conterá as colunas customer\$1id, name, order\$1id e order\$1date.

```
SELECT customers.customer_id, customers.name, orders.order_id, orders.order_date
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;
```

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
```

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 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
```

## ESQUERDA [EXTERNA]
<a name="left-outer-join"></a>

Retorna todos os valores da referência da tabela à esquerda e os valores correspondentes da referência da tabela à direita ou acrescenta NULL se não houver correspondência. Também é conhecida como *junção externa esquerda*. 

Ele retorna todas as linhas da tabela esquerda (primeira) e as linhas correspondentes da tabela direita (segunda). Se não houver correspondência na tabela à direita, o conjunto de resultados conterá valores NULL para as colunas da tabela à direita. A palavra-chave OUTER pode ser omitida e a junção pode ser escrita simplesmente como LEFT JOIN. O oposto de um LEFT OUTER JOIN é um RIGHT OUTER JOIN, que retorna todas as linhas da tabela direita e as linhas correspondentes da tabela esquerda.

**Sintaxe:**

```
SELECT column1, column2, ..., columnn
FROM table1
LEFT [OUTER] JOIN table2
ON table1.column = table2.column;
```

A consulta a seguir retornará todas as linhas da tabela de clientes, junto com as linhas correspondentes da tabela de pedidos. Se um cliente não tiver pedidos, o conjunto de resultados ainda incluirá as informações desse cliente, com valores NULL para as colunas order\$1id e order\$1date.

```
SELECT customers.customer_id, customers.name, orders.order_id, orders.order_date
FROM customers
LEFT OUTER JOIN orders
ON customers.customer_id = orders.customer_id;
```

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
```

## DIREITO [EXTERNO]
<a name="right-outer-join"></a>

Retorna todos os valores da referência da tabela à direita e os valores correspondentes da referência da tabela à esquerda ou acrescenta NULL se não houver correspondência. Também é conhecida como *junção externa direita*.

Ele retorna todas as linhas da tabela direita (segunda) e as linhas correspondentes da tabela esquerda (primeira). Se não houver correspondência na tabela à esquerda, o conjunto de resultados conterá valores NULL para as colunas da tabela à esquerda. A palavra-chave OUTER pode ser omitida e a junção pode ser escrita simplesmente como RIGHT JOIN. O oposto de um RIGHT OUTER JOIN é um LEFT OUTER JOIN, que retorna todas as linhas da tabela esquerda e as linhas correspondentes da tabela direita.

**Sintaxe:**

```
SELECT column1, column2, ..., columnn
FROM table1
RIGHT [OUTER] JOIN table2
ON table1.column = table2.column;
```

A consulta a seguir retornará todas as linhas da tabela de clientes, junto com as linhas correspondentes da tabela de pedidos. Se um cliente não tiver pedidos, o conjunto de resultados ainda incluirá as informações desse cliente, com valores NULL para as colunas order\$1id e order\$1date.

```
SELECT orders.order_id, orders.order_date, customers.customer_id, customers.name
FROM orders
RIGHT OUTER JOIN customers
ON orders.customer_id = customers.customer_id;
```

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
```

## COMPLETO [EXTERNO]
<a name="full-join"></a>

Retorna todos os valores de ambas as relações, anexando valores NULL no lado que não tem correspondência. Também é conhecida como *junção externa completa*. 

Ele retorna todas as linhas das tabelas esquerda e direita, independentemente de haver uma correspondência ou não. Se não houver correspondência, o conjunto de resultados conterá valores NULL para as colunas da tabela que não têm uma linha correspondente. A palavra-chave OUTER pode ser omitida e a junção pode ser escrita simplesmente como FULL JOIN. O FULL OUTER JOIN é menos comumente usado do que o LEFT OUTER JOIN ou o RIGHT OUTER JOIN, mas pode ser útil em determinados cenários em que você precisa ver todos os dados das duas tabelas, mesmo que não haja correspondências.

**Sintaxe:**

```
SELECT column1, column2, ..., columnn
FROM table1
FULL [OUTER] JOIN table2
ON table1.column = table2.column;
```

A consulta a seguir retornará todas as linhas das tabelas de clientes e pedidos. Se um cliente não tiver pedidos, o conjunto de resultados ainda incluirá as informações desse cliente, com valores NULL para as colunas order\$1id e order\$1date. Se um pedido não tiver nenhum cliente associado, o conjunto de resultados incluirá esse pedido, com valores NULL para as colunas customer\$1id e name.

```
SELECT customers.customer_id, customers.name, orders.order_id, orders.order_date
FROM customers
FULL OUTER JOIN orders
ON customers.customer_id = orders.customer_id;
```

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 as linhas que não resultam em nenhuma venda (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
```

## [ESQUERDA] SEMI
<a name="left-semi-join"></a>

Retorna valores do lado esquerdo da referência da tabela que coincidem com o direito. Também é conhecida como *junção semi esquerda*. 

Ele retorna somente as linhas da tabela esquerda (primeira) que têm uma linha correspondente na tabela direita (segunda). Ele não retorna nenhuma coluna da tabela à direita - somente as colunas da tabela à esquerda. O LEFT SEMI JOIN é útil quando você deseja encontrar as linhas em uma tabela que coincidem em outra tabela, sem precisar retornar nenhum dado da segunda tabela. O LEFT SEMI JOIN é uma alternativa mais eficiente ao uso de uma subconsulta com uma cláusula IN ou EXISTS.

**Sintaxe:**

```
SELECT column1, column2, ..., columnn
FROM table1
LEFT SEMI JOIN table2
ON table1.column = table2.column;
```

A consulta a seguir retornará somente as colunas customer\$1id e name da tabela de clientes, para os clientes que têm pelo menos um pedido na tabela de pedidos. O conjunto de resultados não incluirá nenhuma coluna da tabela de pedidos.

```
SELECT customers.customer_id, customers.name
FROM customers
LEFT SEMI JOIN orders
ON customers.customer_id = orders.customer_id;
```

## CROSS JOIN
<a name="cross-join"></a>

Retorna o produto cartesiano de duas relações. Isso significa que o conjunto de resultados conterá todas as combinações possíveis de linhas das duas tabelas, sem nenhuma condição ou filtro aplicado.

O CROSS JOIN é útil quando você precisa gerar todas as combinações possíveis de dados de duas tabelas, como no caso da criação de um relatório que exibe todas as combinações possíveis de informações do cliente e do produto. O CROSS JOIN é diferente de outros tipos de junção (INNER JOIN, LEFT JOIN etc.) porque não tem uma condição de junção na cláusula ON. A condição de junção não é necessária para um CROSS JOIN.

**Sintaxe:**

```
SELECT column1, column2, ..., columnn
FROM table1
CROSS JOIN table2;
```

A consulta a seguir retornará um conjunto de resultados que contém todas as combinações possíveis de customer\$1id, customer\$1name, product\$1id e product\$1name das tabelas de clientes e produtos. Se a tabela de clientes tiver 10 linhas e a tabela de produtos tiver 20 linhas, o conjunto de resultados do CROSS JOIN conterá 10 x 20 = 200 linhas.

```
SELECT customers.customer_id, customers.name, products.product_id, products.product_name
FROM customers
CROSS JOIN products;
```

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
```

## ANTI-JUNÇÃO
<a name="anti-join"></a>

Retorna os valores da referência da tabela à esquerda que não têm correspondência com a referência da tabela à direita. Também é conhecido como *anti-junção esquerda*.

O ANTI JOIN é uma operação útil quando você deseja encontrar as linhas em uma tabela que não coincidem em outra tabela. 

**Sintaxe:**

```
SELECT column1, column2, ..., columnn
FROM table1
LEFT ANTI JOIN table2
ON table1.column = table2.column;
```

A consulta a seguir retornará todos os clientes que não fizeram nenhum pedido.

```
SELECT customers.customer_id, customers.name
FROM customers
LEFT ANTI JOIN orders
ON customers.customer_id = orders.customer_id
WHERE orders.order_id IS NULL;
```

## NATURAL
<a name="natural-join"></a>

Especifica que as linhas das duas relações serão correspondidas implicitamente em igualdade para todas as colunas com nomes correspondentes. 

Ele combina automaticamente colunas com o mesmo nome e tipo de dados entre as duas tabelas. Não é necessário especificar explicitamente a condição de junção na cláusula ON. Ele combina todas as colunas correspondentes entre as duas tabelas no conjunto de resultados.

O NATURAL JOIN é uma abreviatura conveniente quando as tabelas que você está unindo têm colunas com os mesmos nomes e tipos de dados. No entanto, geralmente é recomendável usar o INNER JOIN mais explícito... Sintaxe ON para tornar as condições de junção mais explícitas e fáceis de entender.

**Sintaxe:**

```
SELECT column1, column2, ..., columnn
FROM table1
NATURAL JOIN table2;
```

O exemplo a seguir é uma junção natural entre duas tabelas `employees` e`departments`, com as seguintes colunas: 
+ `employees`tabela:`employee_id`,`first_name`,`last_name`, `department_id `
+ `departments`tabela:`department_id`, `department_name `

A consulta a seguir retornará um conjunto de resultados que inclui o nome, o sobrenome e o nome do departamento para todas as linhas correspondentes entre as duas tabelas, com base na `department_id` coluna.

```
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
NATURAL JOIN departments d;
```

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
```

# Cláusula WHERE
<a name="WHERE_clause"></a>

A cláusula WHERE contém as condições que juntam as tabelas ou aplicam predicados às colunas nas tabelas. Tabelas internas que foram juntadas usando a sintaxe apropriada, seja com a cláusula WHERE ou com a cláusula FROM. Os critérios de junção externa devem ser especificados na cláusula FROM. 

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

```
[ WHERE condition ]
```

## *condição*
<a name="WHERE_clause-synopsis-condition"></a>

Qualquer condição de pesquisa com um resultado booleano, como uma condição de junção ou um predicado em uma coluna de tabela. Os exemplos a seguir são condições de junção válidas: 

```
sales.listid=listing.listid
sales.listid<>listing.listid
```

Os exemplos a seguir são condições válidas nas colunas em tabelas: 

```
catgroup like 'S%'
venueseats between 20000 and 50000
eventname in('Jersey Boys','Spamalot')
year=2008
length(catdesc)>25
date_part(month, caldate)=6
```

As condições podem ser simples ou complexas; para condições complexas, você pode usar parênteses para isolar unidades lógicas. No exemplo a seguir, a condição de junção está entre parênteses. 

```
where (category.catid=event.catid) and category.catid in(6,7,8)
```

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

É possível usar aliases na cláusula WHERE para fazer referência a expressões da lista de seleção. 

Não é possível restringir os resultados de funções agregadas na cláusula WHERE; use a cláusula HAVING para essa finalidade. 

Colunas restringidas na cláusula WHERE devem ser derivadas de referências da tabela na cláusula FROM. 

## Exemplo
<a name="SELECT_synopsis-example"></a>

A consulta a seguir usa uma combinação de diferentes restrições da cláusula WHERE, incluindo uma condição de junção para as tabelas SALES e EVENT, um predicado na coluna EVENTNAME e dois predicados na coluna STARTTIME. 

```
select eventname, starttime, pricepaid/qtysold as costperticket, qtysold
from sales, event
where sales.eventid = event.eventid
and eventname='Hannah Montana'
and date_part(quarter, starttime) in(1,2)
and date_part(year, starttime) = 2008
order by 3 desc, 4, 2, 1 limit 10;

eventname    |      starttime      |   costperticket   | qtysold
----------------+---------------------+-------------------+---------
Hannah Montana | 2008-06-07 14:00:00 |     1706.00000000 |       2
Hannah Montana | 2008-05-01 19:00:00 |     1658.00000000 |       2
Hannah Montana | 2008-06-07 14:00:00 |     1479.00000000 |       1
Hannah Montana | 2008-06-07 14:00:00 |     1479.00000000 |       3
Hannah Montana | 2008-06-07 14:00:00 |     1163.00000000 |       1
Hannah Montana | 2008-06-07 14:00:00 |     1163.00000000 |       2
Hannah Montana | 2008-06-07 14:00:00 |     1163.00000000 |       4
Hannah Montana | 2008-05-01 19:00:00 |      497.00000000 |       1
Hannah Montana | 2008-05-01 19:00:00 |      497.00000000 |       2
Hannah Montana | 2008-05-01 19:00:00 |      497.00000000 |       4
(10 rows)
```

# Cláusula VALUES
<a name="VALUES"></a>

A cláusula VALUES é usada para fornecer um conjunto de valores de linha diretamente na consulta, sem a necessidade de referenciar uma tabela. 

A cláusula VALUES pode ser usada nos seguintes cenários:
+ Você pode usar a cláusula VALUES em uma instrução INSERT INTO para especificar os valores das novas linhas que estão sendo inseridas em uma tabela.
+ Você pode usar a cláusula VALUES sozinha para criar um conjunto de resultados temporário ou uma tabela embutida, sem a necessidade de referenciar uma tabela.
+ Você pode combinar a cláusula VALUES com outras cláusulas SQL, como WHERE, ORDER BY ou LIMIT, para filtrar, classificar ou limitar as linhas no conjunto de resultados.

Essa cláusula é particularmente útil quando você precisa inserir, consultar ou manipular um pequeno conjunto de dados diretamente na instrução SQL, sem a necessidade de criar ou referenciar uma tabela permanente. Ele permite que você defina os nomes das colunas e os valores correspondentes para cada linha, oferecendo a flexibilidade de criar conjuntos de resultados temporários ou inserir dados dinamicamente, sem a sobrecarga de gerenciar uma tabela separada.

## Sintaxe
<a name="VALUES-syntax"></a>

```
VALUES ( expression [ , ... ] ) [ table_alias ]
```

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

 *expressão*   
Uma expressão que especifica uma combinação de um ou mais valores, operadores e funções SQL que resulta em um valor.

 *apelido de tabela*   
Um alias que especifica um nome temporário com uma lista opcional de nomes de colunas.

## Exemplo
<a name="VALUES-example"></a>

O exemplo a seguir cria uma tabela embutida, um conjunto de resultados temporário semelhante a uma tabela com duas colunas e. `col1` `col2` A única linha no conjunto de resultados contém os valores `"one"` e`1`, respectivamente. A `SELECT * FROM` parte da consulta simplesmente recupera todas as colunas e linhas desse conjunto de resultados temporário. Os nomes das colunas (`col1`e`col2`) são gerados automaticamente pelo sistema de banco de dados, porque a cláusula VALUES não especifica explicitamente os nomes das colunas. 

```
SELECT * FROM VALUES ("one", 1);
+----+----+
|col1|col2|
+----+----+
| one|   1|
+----+----+
```

Se quiser definir nomes de colunas personalizados, você pode fazer isso usando uma cláusula AS após a cláusula VALUES, assim:

```
SELECT * FROM (VALUES ("one", 1)) AS my_table (name, id);
+------+----+
| name | id |
+------+----+
| one  |  1 |
+------+----+
```

Isso criaria um conjunto de resultados temporário com os nomes das colunas `name` e`id`, em vez do padrão `col1` `col2` e. 

# Cláusula GROUP BY
<a name="GROUP_BY_clause"></a>

A cláusula GROUP BY identifica as colunas de agrupamento para a consulta. As colunas de agrupamento devem ser declaradas quando a consulta computa agregadas com funções padrão como SUM, AVG e COUNT. Se uma função agregada estiver presente na expressão SELECT, qualquer coluna na expressão SELECT que não esteja em uma função agregada deverá estar na cláusula GROUP BY.

Para obter mais informações, consulte [AWS Clean Rooms Funções do Spark SQL](sql-functions-topic-spark.md). 

## Sintaxe
<a name="r_GROUP_BY_clause-syntax"></a>

```
GROUP BY group_by_clause [, ...]

group_by_clause := {
    expr |
        ROLLUP ( expr [, ...] ) |
        }
```

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

 *expr*  
A lista de colunas ou de expressões deve corresponder à lista de expressões não agregadas na lista de seleção da consulta. Por exemplo, considere a seguinte consulta simples.  

```
select listid, eventid, sum(pricepaid) as revenue,
count(qtysold) as numtix
from sales
group by listid, eventid
order by 3, 4, 2, 1
limit 5;

listid | eventid | revenue | numtix
-------+---------+---------+--------
89397  |      47 |   20.00 |      1
106590 |      76 |   20.00 |      1
124683 |     393 |   20.00 |      1
103037 |     403 |   20.00 |      1
147685 |     429 |   20.00 |      1
(5 rows)
```
Nesta consulta, a lista de seleção consiste em duas expressões agregadas. A primeira usa a função SUM e a segunda usa a função COUNT. As duas colunas restantes, LISTID e EVENTID, devem ser declaradas como colunas de agrupamento.  
As expressões na cláusula GROUP BY também podem fazer referência à lista de seleção usando números ordinais. O exemplo anterior poderia ser abreviado da seguinte forma.  

```
select listid, eventid, sum(pricepaid) as revenue,
count(qtysold) as numtix
from sales
group by 1,2
order by 3, 4, 2, 1
limit 5;

listid | eventid | revenue | numtix
-------+---------+---------+--------
89397  |      47 |   20.00 |      1
106590 |      76 |   20.00 |      1
124683 |     393 |   20.00 |      1
103037 |     403 |   20.00 |      1
147685 |     429 |   20.00 |      1
(5 rows)
```

 *ROLLUP*   
Você pode usar a extensão de agregação ROLLUP para executar o trabalho de múltiplas operações GROUP BY em uma única instrução. Para obter mais informações sobre extensões de agregação e funções relacionadas, consulte [Extensões de agregação](GROUP_BY_aggregation-extensions.md). 

# Extensões de agregação
<a name="GROUP_BY_aggregation-extensions"></a>

AWS Clean Rooms suporta extensões de agregação para realizar o trabalho de várias operações GROUP BY em uma única instrução.

## *GROUPING SETS*
<a name="GROUP_BY_aggregation-extensions-grouping-sets"></a>

 Calcula um ou mais conjuntos de agrupamento em uma única instrução. Um conjunto de agrupamento é o conjunto de uma única cláusula GROUP BY, um conjunto de 0 ou mais colunas pelo qual você pode agrupar o conjunto de resultados de uma consulta. GROUP BY GROUPING SETS é equivalente a executar uma consulta UNION ALL em um conjunto de resultados agrupado por colunas diferentes. Por exemplo, GROUP BY GROUPING SETS((a), (b)) é equivalente a GROUP BY a UNION ALL GROUP BY b. 

 O exemplo a seguir retorna o custo dos produtos da tabela de pedidos agrupados de acordo com as categorias de produtos e o tipo de produto vendido. 

```
SELECT category, product, sum(cost) as total
FROM orders
GROUP BY GROUPING SETS(category, product);

       category       |       product        | total
----------------------+----------------------+-------
 computers            |                      |  2100
 cellphones           |                      |  1610
                      | laptop               |  2050
                      | smartphone           |  1610
                      | mouse                |    50

(5 rows)
```

## *ROLLUP*
<a name="GROUP_BY_aggregation-extensions-rollup"></a>

 Assume uma hierarquia em que as colunas anteriores são consideradas pais das colunas subsequentes. ROLLUP agrupa os dados pelas colunas fornecidas, retornando linhas de subtotal extras representando os totais em todos os níveis de colunas de agrupamento, além das linhas agrupadas. Por exemplo, você pode usar GROUP BY ROLLUP((a), (b)) para retornar um conjunto de resultados agrupado primeiro por a, depois por b, assumindo que b é uma subseção de a. ROLLUP também retorna uma linha com todo o conjunto de resultados sem colunas de agrupamento. 

GROUP BY ROLLUP((a), (b)) é equivalente a GROUP BY GROUPING SETS((a,b), (a), ()). 

O exemplo a seguir retorna o custo dos produtos da tabela de pedidos agrupados primeiro por categoria, depois por produto, com o produto como uma subdivisão da categoria.

```
SELECT category, product, sum(cost) as total
FROM orders
GROUP BY ROLLUP(category, product) ORDER BY 1,2;

       category       |       product        | total
----------------------+----------------------+-------
 cellphones           | smartphone           |  1610
 cellphones           |                      |  1610
 computers            | laptop               |  2050
 computers            | mouse                |    50
 computers            |                      |  2100
                      |                      |  3710
(6 rows)
```

## *CUBE*
<a name="GROUP_BY_aggregation-extensions-cube"></a>

 Agrupa os dados pelas colunas fornecidas, retornando linhas de subtotal extras representando os totais em todos os níveis de colunas de agrupamento, além das linhas agrupadas. CUBE retorna as mesmas linhas que ROLLUP, enquanto inclui linhas de subtotal adicionais para cada combinação de coluna de agrupamento não contemplada por ROLLUP. Por exemplo, você pode usar GROUP BY CUBE((a), (b)) para retornar um conjunto de resultados agrupado primeiro por a, depois por b, assumindo que b é uma subseção de a, depois apenas por b. CUBE também retorna uma linha com todo o conjunto de resultados sem colunas de agrupamento.

GROUP BY CUBE((a), (b)) é equivalente a GROUP BY GROUPING SETS((a,b), (a), (b), ()). 

O exemplo a seguir retorna o custo dos produtos da tabela de pedidos agrupados primeiro por categoria, depois por produto, com o produto como uma subdivisão da categoria. Ao contrário do exemplo anterior para ROLLUP, a instrução retorna resultados para cada combinação de coluna de agrupamento. 

```
SELECT category, product, sum(cost) as total
FROM orders
GROUP BY CUBE(category, product) ORDER BY 1,2;

       category       |       product        | total
----------------------+----------------------+-------
 cellphones           | smartphone           |  1610
 cellphones           |                      |  1610
 computers            | laptop               |  2050
 computers            | mouse                |    50
 computers            |                      |  2100
                      | laptop               |  2050
                      | mouse                |    50
                      | smartphone           |  1610
                      |                      |  3710
(9 rows)
```

# Cláusula HAVING
<a name="HAVING_clause"></a>

A cláusula HAVING aplica uma condição a um conjunto de resultados agrupados intermediários retornados por uma consulta.

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

```
[ HAVING condition ]
```

Por exemplo, você pode restringir os resultados de uma função SUM:

```
having sum(pricepaid) >10000
```

A condição HAVING é aplicada depois que todas as condições da cláusula WHERE forem aplicadas e as operações GROUP BY concluídas.

A própria condição leva a mesma forma que qualquer condição da cláusula WHERE.

## Observações de uso
<a name="HAVING_clause_usage_notes"></a>
+ Qualquer coluna referida na condição da cláusula HAVING deve ser uma coluna de agrupamento ou uma coluna que faz referência ao resultado de uma função agregada.
+ Em uma cláusula HAVING, você não pode especificar:
  + Número ordinal que se refere a um item na lista de seleção. Somente as cláusulas GROUP BY e ORDER BY aceitam números ordinais.

## Exemplos
<a name="HAVING_clause-examples"></a>

A consulta a seguir calcula as vendas de ingressos globais para todos os eventos por nome e depois elimina eventos em que as vendas globais tenham sido menos de \$1 800.000. A condição HAVING é aplicada aos resultados da função agregada na lista de seleção: `sum(pricepaid)`.

```
select eventname, sum(pricepaid)
from sales join event on sales.eventid = event.eventid
group by 1
having sum(pricepaid) > 800000
order by 2 desc, 1;

eventname     |    sum
------------------+-----------
Mamma Mia!       | 1135454.00
Spring Awakening |  972855.00
The Country Girl |  910563.00
Macbeth          |  862580.00
Jersey Boys      |  811877.00
Legally Blonde   |  804583.00
(6 rows)
```

A consulta a seguir calcula um conjunto de resultados semelhante. Nesse caso, no entanto, a condição HAVING é aplicada a um valor agregado não especificado na lista de seleção: `sum(qtysold)`. Os eventos que não tenham vendido mais de 2.000 ingressos são eliminados dos resultados finais.

```
select eventname, sum(pricepaid)
from sales join event on sales.eventid = event.eventid
group by 1
having sum(qtysold) >2000
order by 2 desc, 1;

eventname     |    sum
------------------+-----------
Mamma Mia!       | 1135454.00
Spring Awakening |  972855.00
The Country Girl |  910563.00
Macbeth          |  862580.00
Jersey Boys      |  811877.00
Legally Blonde   |  804583.00
Chicago          |  790993.00
Spamalot         |  714307.00
(8 rows)
```

# Configurar operadores
<a name="UNION"></a>

Os *operadores de conjunto* são usados para comparar e mesclar os resultados de duas expressões de consulta separadas. 

AWS Clean Rooms O Spark SQL é compatível com os seguintes operadores de conjunto listados na tabela a seguir.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/clean-rooms/latest/sql-reference/UNION.html)

Por exemplo, se você quiser saber quais usuários de um site compram e vendem, mas os nomes de usuários estiverem armazenados em colunas ou tabelas separadas, você pode encontrar a *interseção* desses dois tipos de usuários. Se você quiser saber quais usuários do site compram, mas não vendem, você pode usar o operador EXCEPT para encontrar a *diferença* entre as duas listas de usuários. Se quiser criar uma lista com todos os usuários, independentemente da função, use o operador UNION.

**nota**  
As cláusulas ORDER BY, LIMIT, SELECT TOP e OFFSET não podem ser usadas nas expressões de consulta mescladas pelos operadores de conjunto UNION, UNION ALL, INTERSECT e EXCEPT.

**Topics**
+ [Sintaxe](#UNION-synopsis)
+ [Parâmetros](#UNION-parameters)
+ [Ordem de avaliação para operadores de conjunto](#UNION-order-of-evaluation-for-set-operators)
+ [Observações de uso](#UNION-usage-notes)
+ [Exemplos de consultas UNION](example_union_query.md)
+ [Exemplos de consultas UNION ALL](example_unionall_query.md)
+ [Exemplos de consultas INTERSECT](example_intersect_query.md)
+ [Exemplos de consultas EXCEPT](Example_EXCEPT_query.md)

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

```
subquery1
{ { UNION [ ALL | DISTINCT ] |
              INTERSECT [ ALL | DISTINCT ] |
              EXCEPT [ ALL | DISTINCT ] } subquery2 } [...] }
```

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

 *subconsulta1, subconsulta2*   
Uma expressão de consulta que corresponde, no formato de sua lista de seleção, a uma segunda expressão de consulta que segue o operador UNION, UNION ALL, INTERSECT, INTERSECT ALL, EXCEPT ou EXCEPT ALL. As duas expressões devem conter o mesmo número de colunas de saída com tipos de dados compatíveis. Caso contrário, os dois conjuntos de resultados não poderão ser comparados e mesclados. As operações de conjunto não permitem a conversão implícita entre diferentes categorias de tipos de dados. Para obter mais informações, consulte [Compatibilidade e conversão dos tipos](s_Type_conversion.md).  
Você pode criar consultas contendo um número ilimitado de expressões de consulta e conectá-las aos operadores UNION, INTERSECT e EXCEPT em qualquer combinação. Por exemplo, a estrutura de consulta a seguir é válida, pressupondo que as tabelas T1, T2 e T3 contenham conjuntos compatíveis de colunas:   

```
select * from t1
union
select * from t2
except
select * from t3
```

UNIÃO [TUDO \$1 DISTINTO]  
Operação de conjunto que retorna linhas de duas expressões de consulta, independentemente das linhas se derivarem de uma ou ambas as expressões.

CRUZAR [TUDO \$1 DISTINTO]  
Operação de conjunto que retorna linhas derivadas de duas expressões de consulta. As linhas que não forem retornadas por ambas as expressões serão descartadas.

EXCETO [TUDO \$1 DISTINTO]  
Operação de conjunto que retorna linhas derivadas de uma das duas expressões de consulta. Para se qualificar para o resultado, as linhas precisam existir na primeira tabela de resultados, mas não na segunda.   
EXCEPT ALL não remove duplicatas das linhas de resultados.  
MINUS e EXCEPT são sinônimos. 

## Ordem de avaliação para operadores de conjunto
<a name="UNION-order-of-evaluation-for-set-operators"></a>

Os operadores de conjunto UNION e EXCEPT se associam à esquerda. Se não houver parênteses especificados para influenciar a ordem de precedência, uma combinação desses operadores de conjunto será avaliada da esquerda para a direita. Por exemplo, na consulta a seguir, o operador UNION de T1 e T2 é avaliado primeiro, seguido pela operação EXCEPT, que é executada no resultado de UNION: 

```
select * from t1
union
select * from t2
except
select * from t3
```

O operador INTERSECT tem precedência sobre os operadores UNION e EXCEPT quando uma combinação de operadores for usada na mesma consulta. Por exemplo, a consulta a seguir avalia a interseção de T2 e T3, e depois une o resultado com T1: 

```
select * from t1
union
select * from t2
intersect
select * from t3
```

Adicionando parênteses, você pode aplicar uma ordem diferente de avaliação. No caso a seguir, o resultado da união de T1 e T2 é cruzado com T3, e a consulta provavelmente produzirá um resultado diferente. 

```
(select * from t1
union
select * from t2)
intersect
(select * from t3)
```

## Observações de uso
<a name="UNION-usage-notes"></a>
+ Os nomes de colunas obtidos no resultado de uma consulta de operação de conjunto são os nomes de colunas (ou aliases) das tabelas na primeira expressão de consulta. Como esses nomes de coluna podem induzir a erros, os valores na coluna derivam de tabelas em ambos os lados do operador de conjunto, você pode querer fornecer aliases significativos para o conjunto de resultados.
+ Quando as consultas do operador de conjunto retornam resultados decimais, as colunas de resultados correspondentes são promovidas para retornar a mesma precisão e escala. Por exemplo, na consulta a seguir, em que T1.REVENUE é uma coluna DECIMAL(10,2) e T2.REVENUE é uma coluna DECIMAL(8,4), o resultado decimal é atualizado para DECIMAL(12,4): 

  ```
  select t1.revenue union select t2.revenue;
  ```

  A escala é `4` porque é a escala máxima das duas colunas. A precisão é `12` porque T1.REVENUE requer 8 dígitos à esquerda do ponto decimal (12 - 4 = 8). Essa promoção de tipo garante que todos os valores de ambos os lados de UNION se encaixem no resultado. Para valores de 64 bits, a precisão máxima de resultado é 19 e a escala máxima de resultado é 18. Para valores de 128-bits, a precisão máxima de resultado é 38 e a escala máxima de resultado é 37.

  Se o tipo de dados resultante exceder os limites AWS Clean Rooms de precisão e escala, a consulta retornará um erro.
+ Para operações de conjunto, duas linhas são tratadas como idênticas se, para cada par de colunas correspondente, os dois valores de dados forem *iguais* ou *ambos NULL*. Por exemplo, se as tabelas T1 e T2 contiverem uma coluna e uma linha, e a linha for NULL em ambas as tabelas, uma operação INTERSECT sobre essas tabelas retornará essa linha.

# Exemplos de consultas UNION
<a name="example_union_query"></a>

Na consulta UNION a seguir, as linhas na tabela SALES são mescladas com as linhas na tabela LISTING. Três colunas compatíveis de cada tabela são selecionadas. Nesse caso, as colunas correspondentes têm os mesmos nomes e tipos de dados. 

```
select listid, sellerid, eventid from listing
union select listid, sellerid, eventid from sales


listid | sellerid | eventid
--------+----------+---------
1 |    36861 |    7872
2 |    16002 |    4806
3 |    21461 |    4256
4 |     8117 |    4337
5 |     1616 |    8647
```

O exemplo a seguir mostra como você pode adicionar um valor literal de saída de uma consulta UNION para ver qual expressão de consulta produziu cada linha no conjunto de resultados. A consulta identifica linhas da primeira expressão de consulta como “B” (para compradores) e linhas da segunda expressão de consulta como “S” (para vendedores). 

A consulta identifica compradores e vendedores para as transações de ingressos que custem \$110.000 ou mais. A única diferença entre as duas expressões de consulta em ambos os lados do operador UNION é a coluna de junção para a tabela SALES. 

```
select listid, lastname, firstname, username,
pricepaid as price, 'S' as buyorsell
from sales, users
where sales.sellerid=users.userid
and pricepaid >=10000
union
select listid, lastname, firstname, username, pricepaid,
'B' as buyorsell
from sales, users
where sales.buyerid=users.userid
and pricepaid >=10000

listid | lastname | firstname | username |   price   | buyorsell
--------+----------+-----------+----------+-----------+-----------
209658 | Lamb     | Colette   | VOR15LYI |  10000.00 | B
209658 | West     | Kato      | ELU81XAA |  10000.00 | S
212395 | Greer    | Harlan    | GXO71KOC |  12624.00 | S
212395 | Perry    | Cora      | YWR73YNZ |  12624.00 | B
215156 | Banks    | Patrick   | ZNQ69CLT |  10000.00 | S
215156 | Hayden   | Malachi   | BBG56AKU |  10000.00 | B
```

O exemplo a seguir usa um operador UNION ALL porque se forem encontradas linhas duplicadas, elas devem ser mantidas no resultado. Para uma série específica de eventos IDs, a consulta retorna 0 ou mais linhas para cada venda associada a cada evento e 0 ou 1 linha para cada anúncio desse evento. IDs Os eventos são exclusivos para cada linha nas tabelas LISTING e EVENT, mas pode haver várias vendas para a mesma combinação de evento e anúncio IDs na tabela SALES. 

A terceira coluna no conjunto de resultados identifica a origem da linha. Se vier da tabela SALES, “Yes” é marcado na coluna SALESROW. (SALESROW é um alias para SALES.LISTID.) Se a linha vier da tabela LISTING, “No” é marcado na coluna SALESROW. 

Nesse caso, o conjunto de resultados consiste em três linhas de vendas para a lista 500, evento 7787. Em outras palavras, três transações diferentes ocorreram para essa combinação de lista e evento. As outras duas listagens, 501 e 502, não produziram nenhuma venda, então a única linha que a consulta produz para essas listas IDs vem da tabela LISTING (SALESROW = 'Não'). 

```
select eventid, listid, 'Yes' as salesrow
from sales
where listid in(500,501,502)
union all
select eventid, listid, 'No'
from listing
where listid in(500,501,502)

eventid | listid | salesrow
---------+--------+----------
7787 |    500 | No
7787 |    500 | Yes
7787 |    500 | Yes
7787 |    500 | Yes
6473 |    501 | No
5108 |    502 | No
```

Se você executar a mesma consulta sem a palavra-chave ALL, o resultado manterá somente uma das transações de vendas. 

```
select eventid, listid, 'Yes' as salesrow
from sales
where listid in(500,501,502)
union
select eventid, listid, 'No'
from listing
where listid in(500,501,502)

eventid | listid | salesrow
---------+--------+----------
7787 |    500 | No
7787 |    500 | Yes
6473 |    501 | No
5108 |    502 | No
```

# Exemplos de consultas UNION ALL
<a name="example_unionall_query"></a>

O exemplo a seguir usa um operador UNION ALL porque se forem encontradas linhas duplicadas, elas devem ser mantidas no resultado. Para uma série específica de eventos IDs, a consulta retorna 0 ou mais linhas para cada venda associada a cada evento e 0 ou 1 linha para cada anúncio desse evento. IDs Os eventos são exclusivos para cada linha nas tabelas LISTING e EVENT, mas pode haver várias vendas para a mesma combinação de evento e anúncio IDs na tabela SALES.

A terceira coluna no conjunto de resultados identifica a origem da linha. Se vier da tabela SALES, “Yes” é marcado na coluna SALESROW. (SALESROW é um alias para SALES.LISTID.) Se a linha vier da tabela LISTING, “No” é marcado na coluna SALESROW.

Nesse caso, o conjunto de resultados consiste em três linhas de vendas para a lista 500, evento 7787. Em outras palavras, três transações diferentes ocorreram para essa combinação de lista e evento. As outras duas listagens, 501 e 502, não produziram nenhuma venda, então a única linha que a consulta produz para essas listas IDs vem da tabela LISTING (SALESROW = 'Não').

```
select eventid, listid, 'Yes' as salesrow
from sales
where listid in(500,501,502)
union all
select eventid, listid, 'No'
from listing
where listid in(500,501,502)

eventid | listid | salesrow
---------+--------+----------
7787 |    500 | No
7787 |    500 | Yes
7787 |    500 | Yes
7787 |    500 | Yes
6473 |    501 | No
5108 |    502 | No
```

Se você executar a mesma consulta sem a palavra-chave ALL, o resultado manterá somente uma das transações de vendas. 

```
select eventid, listid, 'Yes' as salesrow
from sales
where listid in(500,501,502)
union
select eventid, listid, 'No'
from listing
where listid in(500,501,502)
eventid | listid | salesrow
---------+--------+----------
7787 |    500 | No
7787 |    500 | Yes
6473 |    501 | No
5108 |    502 | No
```

# Exemplos de consultas INTERSECT
<a name="example_intersect_query"></a>

Compare o exemplo a seguir com o primeiro exemplo de UNION. A única diferença entre os dois exemplos é o operador de conjunto usado, mas os resultados são muito diferentes. Somente uma das linhas é a mesma: 

```
235494 |    23875 |    8771
```

 Essa é a única linha no resultado limitado de 5 linhas encontrada em ambas as tabelas.

```
select listid, sellerid, eventid from listing
intersect
select listid, sellerid, eventid from sales

listid | sellerid | eventid
--------+----------+---------
235494 |    23875 |    8771
235482 |     1067 |    2667
235479 |     1589 |    7303
235476 |    15550 |     793
235475 |    22306 |    7848
```

A consulta a seguir encontra eventos (em que foram vendidos ingressos) que ocorreram em locais em Nova York e Los Angeles em março. A diferença entre as duas expressões de consulta é a restrição na coluna VENUECITY.

```
select distinct eventname from event, sales, venue
where event.eventid=sales.eventid and event.venueid=venue.venueid
and date_part(month,starttime)=3 and venuecity='Los Angeles'
intersect
select distinct eventname from event, sales, venue
where event.eventid=sales.eventid and event.venueid=venue.venueid
and date_part(month,starttime)=3 and venuecity='New York City';

eventname
----------------------------
A Streetcar Named Desire
Dirty Dancing
Electra
Running with Annalise
Hairspray
Mary Poppins
November
Oliver!
Return To Forever
Rhinoceros
South Pacific
The 39 Steps
The Bacchae
The Caucasian Chalk Circle
The Country Girl
Wicked
Woyzeck
```

# Exemplos de consultas EXCEPT
<a name="Example_EXCEPT_query"></a>

A tabela CATEGORY no banco de dados contém as seguintes 11 linhas: 

```
 catid | catgroup |  catname  |                  catdesc
-------+----------+-----------+--------------------------------------------
   1   | Sports   | MLB       | Major League Baseball
   2   | Sports   | NHL       | National Hockey League
   3   | Sports   | NFL       | National Football League
   4   | Sports   | NBA       | National Basketball Association
   5   | Sports   | MLS       | Major League Soccer
   6   | Shows    | Musicals  | Musical theatre
   7   | Shows    | Plays     | All non-musical theatre
   8   | Shows    | Opera     | All opera and light opera
   9   | Concerts | Pop       | All rock and pop music concerts
  10   | Concerts | Jazz      | All jazz singers and bands
  11   | Concerts | Classical | All symphony, concerto, and choir concerts
(11 rows)
```

Pressuponha que uma tabela CATEGORY\$1STAGE (tabela de preparação) contém uma linha adicional: 

```
 catid | catgroup |  catname  |                  catdesc
-------+----------+-----------+--------------------------------------------
   1   | Sports   | MLB       | Major League Baseball
   2   | Sports   | NHL       | National Hockey League
   3   | Sports   | NFL       | National Football League
   4   | Sports   | NBA       | National Basketball Association
   5   | Sports   | MLS       | Major League Soccer
   6   | Shows    | Musicals  | Musical theatre
   7   | Shows    | Plays     | All non-musical theatre
   8   | Shows    | Opera     | All opera and light opera
   9   | Concerts | Pop       | All rock and pop music concerts
  10   | Concerts | Jazz      | All jazz singers and bands
  11   | Concerts | Classical | All symphony, concerto, and choir concerts
  12   | Concerts | Comedy    | All stand up comedy performances
(12 rows)
```

Retorne a diferença entre as duas tabelas. Em outras palavras, retorne as linhas que estão na tabela CATEGORY\$1STAGE, mas não na tabela CATEGORY: 

```
select * from category_stage
except
select * from category;

catid | catgroup | catname |             catdesc
-------+----------+---------+----------------------------------
  12  | Concerts | Comedy  | All stand up comedy performances
(1 row)
```

A consulta equivalente a seguir usa o sinônimo MINUS. 

```
select * from category_stage
minus
select * from category;

catid | catgroup | catname |             catdesc
-------+----------+---------+----------------------------------
  12  | Concerts | Comedy  | All stand up comedy performances
(1 row)
```

Se você reverter a ordem das expressões SELECT, a consulta não retornará qualquer linha. 

# Cláusula ORDER BY
<a name="ORDER_BY_clause"></a>

A cláusula ORDER BY classifica o conjunto de resultados de uma consulta.

**nota**  
A expressão ORDER BY mais externa deve ter somente colunas que estejam na lista de seleção.

**Topics**
+ [Sintaxe](#ORDER_BY_clause-synopsis)
+ [Parâmetros](#ORDER_BY_clause-parameters)
+ [Observações de uso](#ORDER_BY_usage_notes)
+ [Exemplos com ORDER BY](Examples_with_ORDER_BY.md)

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

```
[ ORDER BY expression [ ASC | DESC ] ]
[ NULLS FIRST | NULLS LAST ]
[ LIMIT { count | ALL } ]
[ OFFSET start ]
```

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

 *expressão*   
Expressão que define a ordem de classificação do resultado da consulta. Ela consiste em uma ou mais colunas da lista de seleção. Os resultados são obtidos com base na ordem binária UTF-8. Também é possível especificar o seguinte:  
+ Números ordinais que representam a posição de entradas da lista de seleção (ou a posição das colunas na tabela se não houver lista de seleção)
+ Aliases que definem entradas da lista de seleção
Quando a cláusula ORDER BY tiver várias expressões, o conjunto de resultados será classificado de acordo com a primeira expressão, e a segunda expressão será aplicada a linhas que tenham valores correspondentes com os da primeira expressão, e assim por diante.

ASC \$1 DESC   
Opção que define a ordem de classificação para a expressão, da seguinte forma:   
+ ASC: ascendente (por exemplo, de valores numéricos menores para maiores e de "A" a "Z" para strings de caracteres). Se nenhuma opção é especificada, os dados são classificados na ordem ascendente por padrão. 
+ DESC: descendente (de valores numéricos maiores para menores; de "Z" a "A" para strings). 

NULLS FIRST \$1 NULLS LAST  
Opção que especifica se valores NULL devem ser classificados primeiro, antes de valores não nulos, ou por último, depois de valores não nulos. Por padrão, os valores NULL são ordenados e classificados por último na ordem ASC e são ordenados e classificados primeiro na ordem DESC.

LIMIT *number* \$1 ALL   <a name="order-by-clause-limit"></a>
Opção que controla o número de linhas classificadas que a consulta retorna. O número LIMIT deve ser um inteiro positivo. O valor máximo é `2147483647`.   
LIMIT 0 não retorna linhas. Você pode usar essa sintaxe para fins de teste: para garantir que uma consulta seja executada (sem exibir qualquer linha) ou obter uma lista de colunas de uma tabela. Uma cláusula ORDER BY é redundante se você estiver usando LIMIT 0 para obter uma lista de colunas. O valor padrão é LIMIT ALL. 

OFFSET *start*   <a name="order-by-clause-offset"></a>
Opção que especifica para ignorar o número de linhas antes de *start* antes de começar a retornar linhas. O número OFFSET deve ser um inteiro positivo. O valor máximo é `2147483647`. Quando usadas com a opção de LIMIT, as linhas OFFSET são ignoradas antes de iniciar a contagem de linhas LIMIT que são retornadas. Se a opção LIMIT não for usada, o número de linhas no conjunto de resultados será reduzido para o número de linhas ignoradas. As linhas ignoradas por uma cláusula OFFSET ainda precisam passar por varredura, e pode não ser eficiente usar um valor OFFSET grande.

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

 Observe o seguinte comportamento esperado com cláusulas ORDER BY: 
+ Os valores NULL são considerados "mais altos" que todos os demais valores. Com a ordem de classificação crescente padrão, os valores NULL são classificados no final. Para alterar esse comportamento, use a opção NULLS FIRST.
+ Quando uma consulta não tiver uma cláusula ORDER BY, o sistema retornará conjuntos de resultados sem uma classificação previsível das linhas. A mesma consulta executada duas vezes pode retornar o conjunto de resultados em uma ordem diferente. 
+ As opções LIMIT e OFFSET podem ser usadas sem uma cláusula ORDER BY. No entanto, para obter um conjunto consistente de linhas, use essas opções em conjunto com ORDER BY. 
+ Em qualquer sistema paralelo, por exemplo AWS Clean Rooms, quando ORDER BY não produz uma ordenação exclusiva, a ordem das linhas não é determinística. Ou seja, se a expressão ORDER BY produzir valores duplicados, a ordem de retorno dessas linhas poderá variar de outros sistemas ou de uma execução AWS Clean Rooms para a próxima. 
+ AWS Clean Rooms não suporta literais de string nas cláusulas ORDER BY.

# Exemplos com ORDER BY
<a name="Examples_with_ORDER_BY"></a>

Retorne todas as 11 linhas da tabela CATEGORY, classificada pela segunda coluna, CATGROUP. Para os resultados que têm o mesmo valor de CATGROUP, classifique os valores da coluna CATDESC pelo tamanho da string. Depois, organize pelas colunas CATID e CATNAME. 

```
select * from category order by 2, 1, 3;

catid | catgroup |  catname  |                  catdesc
-------+----------+-----------+----------------------------------------
10 | Concerts | Jazz      | All jazz singers and bands
9 | Concerts | Pop       | All rock and pop music concerts
11 | Concerts | Classical | All symphony, concerto, and choir conce
6 | Shows    | Musicals  | Musical theatre
7 | Shows    | Plays     | All non-musical theatre
8 | Shows    | Opera     | All opera and light opera
5 | Sports   | MLS       | Major League Soccer
1 | Sports   | MLB       | Major League Baseball
2 | Sports   | NHL       | National Hockey League
3 | Sports   | NFL       | National Football League
4 | Sports   | NBA       | National Basketball Association
(11 rows)
```

Retorne colunas selecionadas da tabela SALES, classificada pelos valores mais altos de QTYSOLD. Limite o resultado às 10 primeiras linhas: 

```
select salesid, qtysold, pricepaid, commission, saletime from sales
order by qtysold, pricepaid, commission, salesid, saletime desc

salesid | qtysold | pricepaid | commission |      saletime
---------+---------+-----------+------------+---------------------
15401 |       8 |    272.00 |      40.80 | 2008-03-18 06:54:56
61683 |       8 |    296.00 |      44.40 | 2008-11-26 04:00:23
90528 |       8 |    328.00 |      49.20 | 2008-06-11 02:38:09
74549 |       8 |    336.00 |      50.40 | 2008-01-19 12:01:21
130232 |       8 |    352.00 |      52.80 | 2008-05-02 05:52:31
55243 |       8 |    384.00 |      57.60 | 2008-07-12 02:19:53
16004 |       8 |    440.00 |      66.00 | 2008-11-04 07:22:31
489 |       8 |    496.00 |      74.40 | 2008-08-03 05:48:55
4197 |       8 |    512.00 |      76.80 | 2008-03-23 11:35:33
16929 |       8 |    568.00 |      85.20 | 2008-12-19 02:59:33
```

Retorne uma lista de colunas e nenhuma linha usando a sintaxe LIMIT 0: 

```
select * from venue limit 0;
venueid | venuename | venuecity | venuestate | venueseats
---------+-----------+-----------+------------+------------
(0 rows)
```

# Exemplos de subconsulta
<a name="Subquery_examples"></a>

Os exemplos a seguir mostram diferentes maneiras em que subconsultas se encaixam em consultas SELECT. Consulte [Exemplo](join-clause.md#Join_examples) para obter outros exemplos de uso de subconsultas. 

## Subconsulta da lista SELECT
<a name="Subquery_examples-select-list-subquery"></a>

O exemplo a seguir contém um subconsulta na lista SELECT. Esta subconsulta é *escalar*: retorna somente uma coluna e um valor, que é repetido nos resultados para cada linha retornada da consulta exterior. A consulta compara o valor Q1SALES que a subconsulta computa com valores de vendas de outros dois trimestres (2 e 3) em 2008, como definido pela consulta externa. 

```
select qtr, sum(pricepaid) as qtrsales,
(select sum(pricepaid)
from sales join date on sales.dateid=date.dateid
where qtr='1' and year=2008) as q1sales
from sales join date on sales.dateid=date.dateid
where qtr in('2','3') and year=2008
group by qtr
order by qtr;

qtr  |  qtrsales   |   q1sales
-------+-------------+-------------
2     | 30560050.00 | 24742065.00
3     | 31170237.00 | 24742065.00
(2 rows)
```

## Subconsulta da cláusula WHERE
<a name="Subquery_examples-where-clause-subquery"></a>

O exemplo a seguir contém um subconsulta de tabela na cláusula WHERE. Essa subconsulta produz várias linhas. Nesse caso, as linhas contêm apenas uma coluna, mas as subconsultas da tabela podem conter várias colunas e linhas, assim como qualquer outra tabela. 

A consulta encontra os 10 principais vendedores em termos quantidade máxima de ingressos vendidos. A lista dos 10 principais é restringida pela subconsulta, que remove usuários que vivem em cidades onde há locais de venda de ingressos. Essa consulta pode ser gravada de diferentes maneiras. Por exemplo, a subconsulta pode ser regravada como uma junção na consulta principal. 

```
select firstname, lastname, city, max(qtysold) as maxsold
from users join sales on users.userid=sales.sellerid
where users.city not in(select venuecity from venue)
group by firstname, lastname, city
order by maxsold desc, city desc
limit 10;

firstname | lastname  |      city      | maxsold
-----------+-----------+----------------+---------
Noah       | Guerrero | Worcester      |       8
Isadora    | Moss     | Winooski       |       8
Kieran     | Harrison | Westminster    |       8
Heidi      | Davis    | Warwick        |       8
Sara       | Anthony  | Waco           |       8
Bree       | Buck     | Valdez         |       8
Evangeline | Sampson  | Trenton        |       8
Kendall    | Keith    | Stillwater     |       8
Bertha     | Bishop   | Stevens Point  |       8
Patricia   | Anderson | South Portland |       8
(10 rows)
```

## Subconsultas da cláusula WITH
<a name="Subquery_examples-with-clause-subqueries"></a>

Consulte [Cláusula WITH](WITH_clause.md). 

# Subconsultas correlacionadas
<a name="correlated_subqueries"></a>

O exemplo a seguir contém uma *subconsulta correlacionada* na cláusula WHERE. Esse tipo de subconsulta contém uma ou mais correlações entre as colunas e as colunas produzidas pela consulta externa. Nesse caso, a correlação é `where s.listid=l.listid`. Para cada linha que a consulta externa produz, a subconsulta é executada para qualificar ou desqualificar a linha. 

```
select salesid, listid, sum(pricepaid) from sales s
where qtysold=
(select max(numtickets) from listing l
where s.listid=l.listid)
group by 1,2
order by 1,2
limit 5;

salesid | listid |   sum
--------+--------+----------
 27     |     28 | 111.00
 81     |    103 | 181.00
 142    |    149 | 240.00
 146    |    152 | 231.00
 194    |    210 | 144.00
(5 rows)
```

## Padrões de subconsultas correlacionadas não compatíveis
<a name="correlated_subqueries-correlated-subquery-patterns-that-are-not-supported"></a>

O planejador de consultas usa um método de regravação de consulta chamado decorrelação de subconsultas para otimizar vários padrões de subconsultas correlacionadas para execução em um ambiente de processamento paralelo massivo (MPP). Alguns tipos de subconsultas correlacionadas seguem padrões que não AWS Clean Rooms podem ser correlacionados e não são compatíveis. Consultas que contenham erros de retorno das seguintes referências de correlação: 
+  Referências de correlação que ignoram um bloco de consultas, também conhecidas como "referências de correlação para ignorar consultas". Por exemplo, na consulta a seguir, o bloco contendo a referência de correlação e o bloco ignorado estão conectados por um predicado NOT EXISTS: 

  ```
  select event.eventname from event
  where not exists
  (select * from listing
  where not exists
  (select * from sales where event.eventid=sales.eventid));
  ```

  O bloco ignorado nesse caso é a subconsulta na tabela LISTING. A referência de correlação correlaciona as tabelas EVENT e SALES. 
+  Referências de correlação de uma subconsulta que é parte de uma cláusula ON em uma consulta externa: 

  ```
  select * from category
  left join event
  on category.catid=event.catid and eventid =
  (select max(eventid) from sales where sales.eventid=event.eventid);
  ```

  A cláusula ON contém uma referência de correlação de SALES na subconsulta de EVENT na consulta externa. 
+ Referências de correlação sensíveis a nulos a uma tabela do sistema. AWS Clean Rooms Por exemplo: 

  ```
  select attrelid
  from my_locks sl, my_attribute
  where sl.table_id=my_attribute.attrelid and 1 not in
  (select 1 from my_opclass where sl.lock_owner = opcowner);
  ```
+ Referências de correlação de dentro de uma subconsulta que contém uma função de janela. 

  ```
  select listid, qtysold
  from sales s
  where qtysold not in
  (select sum(numtickets) over() from listing l where s.listid=l.listid);
  ```
+ Referências em uma coluna GROUP BY para os resultados de um subconsulta correlacionada. Por exemplo: 

  ```
  select listing.listid,
  (select count (sales.listid) from sales where sales.listid=listing.listid) as list
  from listing
  group by list, listing.listid;
  ```
+ Referências de correlação de uma subconsulta com uma função agregada e uma cláusula GROUP BY, conectada à consulta externa por um predicado IN. (Essa restrição não se aplica a funções agregadas MIN e MAX.) Por exemplo: 

  ```
  select * from listing where listid in
  (select sum(qtysold)
  from sales
  where numtickets>4
  group by salesid);
  ```