Академический Документы
Профессиональный Документы
Культура Документы
Recupera linhas do banco de dados e permite a seleção de uma ou várias linhas ou colunas de uma ou
várias tabelas no SQL Server. A sintaxe completa da instrução SELECT é complexa, mas as cláusulas
principais podem ser assim resumidas:
[ GROUP BY group_by_expression ]
[ HAVING search_condition ]
Os operadores UNION, EXCEPT e INTERSECT podem ser usados entre consultas para combinar ou
comparar os resultados em um único conjunto de resultados.
Sintaxe
SQL
-- Syntax for SQL Server and Azure SQL Database
Remarks
1
FROM Cláusula FOR
WHERE Cláusula OPTION
GROUP BY
A ordem das cláusulas na instrução SELECT é significativa. Qualquer uma das cláusulas opcionais
pode ser omitida, mas quando elas são usadas devem aparecer na ordem apropriada.
As instruções SELECT serão permitidas em funções definidas pelo usuário apenas se as listas de
seleção dessas instruções contiverem expressões que atribuam valores a variáveis que são locais a
essas funções.
Um nome de quatro partes construído com a função OPENDATASOURCE como a parte do nome
do servidor pode ser usado como uma origem de tabela sempre que um nome de tabela puder
aparecer em uma instrução SELECT. Um nome de quatro partes não pode ser especificado para Banco
de dados SQL do Azure.
Algumas restrições de sintaxe se aplicam a instruções SELECT que envolvem tabelas remotas.
1. FROM 7. HAVING
2. ON 8. SELECT
3. JOIN 9. DISTINCT
4. WHERE 10. ORDER BY
5. GROUP BY 11. INICIO
6. WITH CUBE ou WITH ROLLUP
Aviso
A sequência anterior geralmente é verdadeira. No entanto, há casos incomuns em que a sequência
pode ser diferente.
Por exemplo, suponha que você tenha um índice clusterizado em uma exibição e a exibição exclui
algumas linhas de tabela e lista de colunas SELECT da exibição usa um CONVERT que altera um tipo de
dados de varchar para integer. Nessa situação, CONVERT pode ser executado antes da execução da
cláusula WHERE. Isso é um tanto incomum. Geralmente, há uma maneira de modificar a exibição para
evitar a sequência diferente, se isso é importante em seu caso.
2
Permissões
A seleção de dados exige a permissão SELECT na tabela ou exibição, que pode ser herdada de um escopo
superior, como a permissão SELECT no esquema ou a permissão CONTROL na tabela.Ou exige a associação à
função de banco de dados fixa db_datareader ou db_owner ou à função de servidor fixa sysadmin. A
criação de uma nova tabela com SELECTINTO também exige a permissão CREATETABLE e a
permissão ALTERSCHEMA no esquema que possui a nova tabela.
Exemplos:
Esta seção mostra três exemplos de código. Este primeiro exemplo de código retorna todas as
linhas (nenhuma cláusula WHERE foi especificada) e todas as colunas (usando o *) da
tabela DimEmployee.
SQL
SELECT *
FROM DimEmployee
ORDER BY LastName;
Este próximo exemplo usa a definição de alias da tabela para obter o mesmo resultado.
SQL
SELECT e.*
FROM DimEmployee AS e
ORDER BY LastName;
Este exemplo retorna todas as linhas (nenhuma cláusula WHERE foi especificada) e um subconjunto das
colunas (FirstName, LastName, StartDate) da tabela DimEmployee no banco de
dados AdventureWorksPDW2012. O terceiro título de coluna é renomeado como FirstDay.
SQL
SELECT FirstName, LastName, StartDate AS FirstDay
FROM DimEmployee
ORDER BY LastName;
Este exemplo retorna somente as linhas de DimEmployee que têm uma EndDate que não é NULL e
um MaritalStatus igual a 'M' (married, casado).
SQL
SELECT FirstName, LastName, StartDate AS FirstDay
FROM DimEmployee
WHERE EndDate IS NOT NULL
AND MaritalStatus = 'M'
ORDER BY LastName;
3
O exemplo a seguir retorna todas as linhas da tabela DimEmployee e calcula o pagamento bruto de cada
funcionário com base em sua BaseRate e em uma semana de trabalho de 40 horas.
SQL
SELECT FirstName, LastName, BaseRate, BaseRate * 40 AS GrossPay
FROM DimEmployee
ORDER BY LastName;
O exemplo a seguir usa DISTINCT para gerar uma lista de todos os títulos exclusivos na tabela DimEmployee.
SQL
SELECT DISTINCT Title
FROM DimEmployee
ORDER BY Title;
D. Usando GROUP BY
SQL
SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
ORDER BY OrderDateKey;
Devido à cláusula GROUP BY, somente uma linha que contém a soma de todas as vendas é retornada para
cada dia.
O exemplo a seguir localiza o preço médio e a soma de vendas pela Internet de cada dia, agrupados por data
do pedido e código promocional.
SQL
SELECT OrderDateKey, PromotionKey, AVG(SalesAmount) AS AvgSales,
SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey, PromotionKey
ORDER BY OrderDateKey;
O exemplo a seguir põe os resultados em grupos depois de recuperar apenas as linhas com datas de pedido
posteriores a 1º de agosto de 2002.
SQL
SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
WHERE OrderDateKey > '20020801'
GROUP BY OrderDateKey
ORDER BY OrderDateKey;
4
G. Usando GROUP BY com uma expressão
O exemplo a seguir agrupa por uma expressão. É possível agrupar por uma expressão se a mesma não
contiver funções de agregação.
SQL
SELECT SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY (OrderDateKey * 10);
O exemplo a seguir localiza a soma de vendas por dia e os pedidos por dia.
SQL
SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
ORDER BY OrderDateKey;
SQL
SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
HAVING OrderDateKey > 20010000
ORDER BY OrderDateKey;
Sintaxe
SQL
[ INTO new_table ]
[ ON filegroup ]
Argumentos
new_table
Especifica o nome de uma nova tabela a ser criada com base nas colunas da lista de seleção e nas
linhas escolhidas na origem dos dados.
O formato de new_table é determinado pela avaliação das expressões na lista de seleção. As colunas
na new_table são criadas na ordem especificada pela lista de seleção. Cada coluna em new_table tem o
mesmo nome, tipo de dados, nulidade e valor que a expressão correspondente na lista de seleção. A
5
propriedade IDENTITY de uma coluna é transferida, exceto nas condições definidas em "Trabalhando
com colunas de identidade", na seção Comentários.
Para criar a tabela em outro banco de dados na mesma instância do SQL Server, especifique
new_table como um nome totalmente qualificado no formato database.schema.table_name.
Não é possível criar new_table em um servidor remoto. No entanto, você pode popular
new_table de uma fonte de dados remota. Para criar new_table de uma tabela de origem remota,
especifique a tabela de origem usando um nome de quatro partes no formato
linked_server.catálogo.esquema.objeto na cláusula FROM da instrução SELECT. Como alternativa, é
possível usar a função OPENQUERY ou a função OPENDATASOURCE na cláusula FROM para especificar
a fonte de dados remota.
filegroup
Especifica o nome do grupo de arquivos no qual a nova tabela será criada. O grupo de arquivos
especificado deverá existir no banco de dados, caso contrário, o mecanismo do SQL Server gerará um
erro.
Tipos de dados
O atributo FILESTREAM não é transferido para a nova tabela. Os BLOBs do FILESTREAM são
copiados e armazenados na nova tabela como BLOBs varbinary(max) . Sem o atributo FILESTREAM, o
tipo de dados varbinary(max) tem uma limitação de 2 GB. Se um FILESTREAM BLOB exceder esse valor,
ocorrerá o erro 7119, e a instrução será interrompida.
Quando uma coluna de identidade existente é seleciona para uma nova tabela, a nova coluna
herda a propriedade IDENTITY, a menos que uma das seguintes condições seja verdadeira:
Se alguma dessas condições for verdadeira, a coluna será criada como NOT NULL em vez de
herdar a propriedade IDENTITY. Se uma coluna de identidade for obrigatória na nova tabela, mas não
estiver disponível, ou se você desejar um valor de semente ou de incremento diferente da coluna de
identidade de origem, defina a coluna na lista de seleção que usa a função IDENTITY. Consulte "Criando
uma coluna de identidade usando a função IDENTITY" na seção Exemplos abaixo.
Remarks
A instrução SELECT...INTO opera em duas partes – a nova tabela é criada e, em seguida, as linhas
são inseridas. Isso significa que, se as inserções falharem, elas serão todas revertidas, mas a nova
tabela (vazia) permanecerá. Se você precisar que toda a operação tenha êxito ou falhe como um todo,
use uma transação explícita.
Limitações e Restrições
Não é possível especificar uma variável de tabela ou um parâmetro com valor de tabela como a
nova tabela.
6
Você não pode usar SELECT...INTO para criar uma tabela particionada, mesmo quando a tabela de
origem está particionada. SELECT...INTO não usa o esquema de partição da tabela de origem; em vez
disso, a nova tabela é criada no grupo de arquivos padrão. Para inserir linhas em uma tabela
particionada, crie primeiro a tabela particionada e depois use a instrução INSERT
INTO...SELECT...FROM.
Índices, restrições e gatilhos definidos na tabela de origem não são transferidos para a nova
tabela, nem podem ser especificados na instrução SELECT...INTO. Se esses objetos forem obrigatórios,
você poderá criá-los depois de executar a instrução SELECT...INTO.
Especificar uma cláusula ORDER BY não garante que as linhas sejam inseridas na ordem
especificada.
Quando uma coluna esparsa é incluída na lista de seleção, a propriedade da coluna esparsa não é
transferida para a coluna na nova tabela. Se essa propriedade for necessária na nova tabela, altere a
definição de coluna depois de executar a instrução SELECT... INTO para incluir essa propriedade.
Quando uma coluna computada é incluída na lista de seleção, a coluna correspondente na nova
tabela não é uma coluna computada. Os valores na nova coluna são os que foram calculados no
momento em que a SELECT...INTO foi executada.
Comportamento de log
Permissões
SELECT – HAVING
Especifica um critério de pesquisa para um grupo ou uma agregação. HAVING pode ser usado
somente com a instrução SELECT. HAVING é normalmente usado com uma cláusula GROUP BY.
Quando GROUP BY não for usado, haverá um único grupo agregado e implícito.
Sintaxe
SQL
[ HAVING <search condition> ]
<search_condition> especifica um ou mais predicados aos quais os grupos e/ou as agregações devem
corresponder.
Os tipos de dados text, image e ntext não podem ser usados em uma cláusula HAVING.
Exemplos
O exemplo a seguir que usa uma cláusula simples HAVING recupera o total para cada SalesOrderID da
tabela SalesOrderDetail que excede $100000.00.
7
SQL
USE AdventureWorks2012 ;
GO
SELECT SalesOrderID, SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID
HAVING SUM(LineTotal) > 100000.00
ORDER BY SalesOrderID ;
SELECT – GROUP BY
Uma cláusula da instrução SELECT que divide o resultado da consulta em grupos de linhas,
normalmente, com a finalidade de executar uma ou mais agregações em cada grupo. A instrução
SELECT retorna uma linha por grupo.
Sintaxe
SQL
-- Syntax for SQL Server and Azure SQL Database
-- ISO-Compliant Syntax
GROUP BY {
column-expression
| ROLLUP ( <group_by_expression> [ ,...n ] )
| CUBE ( <group_by_expression> [ ,...n ] )
| GROUPING SETS ( <grouping_set> [ ,...n ] )
| () --calculates the grand total
} [ ,...n ]
<group_by_expression> ::=
column-expression
| ( column-expression [ ,...n ] )
<grouping_set> ::=
() --calculates the grand total
| <grouping_set_item>
| ( <grouping_set_item> [ ,...n ] )
<grouping_set_item> ::=
<group_by_expression>
| ROLLUP ( <group_by_expression> [ ,...n ] )
| CUBE ( <group_by_expression> [ ,...n ] )
GROUP BY
[ ALL ] column-expression [ ,...n ]
| column-expression [ ,...n ] [ WITH { CUBE | ROLLUP } ]
8
Argumentos
column-expression
Especifica uma coluna ou um cálculo de não agregação em uma coluna. Essa coluna pode
pertencer a uma tabela, a uma tabela derivada ou a uma exibição. A coluna precisa aparecer na
cláusula FROM da instrução SELECT, mas não precisa aparecer na lista de SELECT.
A coluna precisa aparecer na cláusula FROM da instrução SELECT, mas não precisa aparecer na
lista de SELECT. No entanto, cada coluna de tabela ou de exibição em qualquer expressão de não
agregação na lista de <select> precisa estar incluída na lista de GROUP BY:
SQL
SELECT ColumnA, ColumnB FROM T GROUP BY ColumnA, ColumnB;
SELECT ColumnA + ColumnB FROM T GROUP BY ColumnA, ColumnB;
SELECT ColumnA + ColumnB FROM T GROUP BY ColumnA + ColumnB;
SELECT ColumnA + ColumnB + constant FROM T GROUP BY ColumnA, ColumnB;
SQL
SELECT ColumnA, ColumnB FROM T GROUP BY ColumnA + ColumnB;
SELECT ColumnA + constant + ColumnB FROM T GROUP BY ColumnA + ColumnB;
Um alias de coluna definido na lista de SELECT. Ela pode usar um alias de coluna para uma tabela
derivada definida na cláusula FROM.
Uma coluna do tipo text, ntext ou image. No entanto, você pode usar uma coluna de texto, ntext
ou imagem como um argumento para uma função que retorna um valor de um tipo de dados
válido. Por exemplo, a expressão pode usar SUBSTRING() e CAST(). Isso também se aplica às
expressões na cláusula HAVING.
Métodos do tipo de dados XML. Ela pode incluir uma função definida pelo usuário que usa
métodos do tipo de dados XML. Ela pode incluir uma coluna computada que usa métodos do tipo
de dados XML.
Uma subconsulta. O erro 144 é retornado.
Uma coluna de uma exibição indexada.
Agrupa os resultados da instrução SELECT de acordo com os valores em uma lista de uma ou mais
expressões de coluna.
Por exemplo, essa consulta cria a tabela Vendas com as colunas País, Região e Vendas. Ela insere
quatro linhas e duas das linhas têm valores correspondentes para País e Região.
9
SQL
CREATE TABLE Sales ( Country varchar(50), Region varchar(50), Sales int );
Região
País Sales
Alberta
Canada 100
Colúmbia Britânica
Canada 200
Colúmbia Britânica
Canada 300
Estados Unidos
Montana 100
Essa próxima consulta agrupa País e Região e retorna a soma de agregação para cada combinação
de valores.
SQL
SELECT Country, Region, SUM(sales) AS TotalSales
FROM Sales
GROUP BY Country, Region;
Região
País Sales
Alberta
Canada 100
Colúmbia Britânica
Canada 500
Estados Unidos
Montana 100
GROUP BY ROLLUP
Cria um grupo para cada combinação de expressões de coluna. Além disso, ele "acumula" os resultados
em subtotais e totais gerais. Para isso, ele vai da direita para a esquerda, diminuindo o número de
expressões de coluna sobre as quais ele cria grupos e agregações.
A ordem da coluna afeta a saída de ROLLUP e pode afetar o número de linhas no conjunto de
resultados.
10
Por exemplo, GROUP BY ROLLUP (col1, col2, col3, col4) cria grupos para cada combinação de
expressões de coluna nas listas a seguir.
Usando a tabela do exemplo anterior, esse código executa uma operação de GROUP BY ROLLUP em
vez de um GROUP BY simples.
SQL
SELECT Country, Region, SUM(Sales) AS TotalSales
FROM Sales
GROUP BY ROLLUP (Country, Region);
O resultado da consulta tem as mesmas agregações que o GROUP BY simples sem o ROLLUP.Além
disso, ele cria subtotais para cada valor de País. Por fim, ele fornece um total geral para todas as linhas. O
resultado será semelhante a este:
Região
País Sales
Alberta
Canada 100
Colúmbia Britânica
Canada 500
NULL
Canada 600
Estados Unidos
Montana 100
Estados Unidos
NULL 100
GROUP BY CUBE ( )
GROUP BY CUBE cria grupos para todas as combinações de colunas possíveis. GROUP BY CUBE (a, b) os
resultados têm grupos de valores exclusivos de (a, b), (NULL, b), (a, NULL) e (NULL, NULL).
Usando a tabela dos exemplos anteriores, esse código executa uma operação de GROUP BY CUBE em
País e em Região.
SQL
SELECT Country, Region, SUM(Sales) AS TotalSales
FROM Sales
GROUP BY CUBE (Country, Region);
O resultado da consulta tem grupos de valores exclusivos (País, Região), (NULL, Região), (País, NULL) e
(NULL, NULL). Os resultados serão semelhantes a estes:
11
País Região Sales
Canada Alberta 100
NULL Alberta 100
Canada Colúmbia Britânica 500
NULL Colúmbia Britânica 500
Estados Unidos Montana 100
NULL Montana 100
NULL NULL 700
Canada NULL 600
Estados Unidos NULL 100
A opção de GROUPING SETS oferece a capacidade de combinar várias cláusulas GROUP BY em uma
única cláusula GROUP BY. Os resultados são o equivalente de UNION ALL dos grupos especificados.
Por exemplo, GROUP BY ROLLUP (Country, Region) e GROUP BY GROUPING SETS ( ROLLUP (Country,
Region) ) retornam os mesmos resultados.
Quando conjuntos de GROUPING SETS têm dois ou mais elementos, os resultados são uma união dos
elementos. Este exemplo retorna a união dos resultados de ROLLUP e CUBE para País e Região.
SQL
SELECT Country, Region, SUM(Sales) AS TotalSales
FROM Sales
GROUP BY GROUPING SETS ( ROLLUP (Country, Region), CUBE (Country, Region) );
Os resultados são iguais, pois essa consulta retorna uma união de duas instruções GROUP BY.
SQL
SELECT Country, Region, SUM(Sales) AS TotalSales
FROM Sales
GROUP BY ROLLUP (Country, Region)
UNION ALL
SELECT Country, Region, SUM(Sales) AS TotalSales
FROM Sales
GROUP BY CUBE (Country, Region);
O SQL não consolida grupos duplicados gerados por uma lista de GROUPING SETS. Por exemplo,
em GROUP BY ( (), CUBE (Country, Region) ), ambos os elementos retornarão uma linha para o total geral e
ambas as linhas serão listadas nos resultados.
GROUP BY ()
Especifica o grupo vazio que gera o total geral. Isso é útil como um dos elementos de um GROUPING
SET. Por exemplo, está instrução fornece o total de vendas para cada país e, em seguida, o total geral para
todos os países.
SQL
SELECT Country, SUM(Sales) AS TotalSales
12
FROM Sales
GROUP BY GROUPING SETS ( Country, () );
GROUP BY [ ALL ] column-expression [ ,...n ]
OBSERVAÇÃO: Esta sintaxe é fornecida apenas para fins de compatibilidade com versões
anteriores. Ela será removida em uma versão futura. Evite usar essa sintaxe em novos trabalhos de
desenvolvimento e planeje modificar os aplicativos que a usam no momento.
Especifica a inclusão de todos os grupos nos resultados, independentemente se eles atendem aos
critérios de pesquisa na cláusula WHERE. Os grupos que não atendem aos critérios de pesquisa têm NULL
para a agregação.
GROUP BY ALL:
Não é compatível com consultas que acessam tabelas remotas quando também há uma cláusula
WHERE na consulta.
Falhará em colunas que têm o atributo FILESTREAM.
WITH (DISTRIBUTED_AGG)
Comentários gerais
Lista de SELECT:
Agregações de vetor. Se funções de agregação são incluídas na lista de SELECT, GROUP BY calcula
um valor resumido para cada grupo. São conhecidas como agregações de vetor.
Agregações de distinção. As agregações AVG (DISTINCT column_name), COUNT (DISTINCT
column_name) e SUM (DISTINCT column_name) são compatíveis com ROLLUP, CUBE e
GROUPING SETS.
Cláusula WHERE:
O SQL remove as linhas que não atendem às condições na cláusula WHERE antes que qualquer
operação de agrupamento seja executada.
Cláusula HAVING:
13
Cláusula ORDER BY:
Use a cláusula ORDER BY para ordenar o conjunto de resultados. A cláusula GROUP BY não
ordena o conjunto de resultados.
Valores NULL:
Se uma coluna de agrupamento contiver valores NULL, todos os valores NULL serão considerados
iguais e serão coletados em um único grupo.
Combina os resultados de duas ou mais consultas em um único conjunto de resultados. Esse conjunto
inclui todas as linhas que pertencem a todas as consultas na união. A operação UNION é diferente de usar
junções que combinam colunas de duas tabelas.
A seguir são apresentadas as regras básicas de combinação dos conjuntos de resultados de duas
consultas usando UNION:
Sintaxe
SQL
{ <query_specification> | ( <query_expression> ) }
{ UNION [ ALL ]
{ <query_specification> | ( <query_expression> ) }
[ ...n ] }
Argumentos
As colunas do tipo de dados xml precisam ser iguais. Todas as colunas devem ter tipo para um
esquema XML ou sem-tipo. Se tiverem tipo, elas deverão ter o tipo igual ao da coleção de esquema XML.
UNION
Especifica que vários conjuntos de resultados serão combinados e retornados como um único conjunto de
resultados.
14
ALL
Incorpora todas as linhas nos resultados, incluindo duplicatas. Se não for especificado, as linhas duplicadas
serão removidas.
No exemplo a seguir, o conjunto de resultados inclui o conteúdo das colunas ProductModelID e Name
das tabelas ProductModel e Gloves.
SQL
-- Uses AdventureWorks
Classifica dados retornados por uma consulta no SQL Server. Use esta cláusula para:
Observação
ORDER BY não é compatível com as instruções SELECT/INTO ou CREATE TABLE AS SELECT (CTAS) no
Azure SQL Data Warehouse nem no Parallel Data Warehouse.
Sintaxe
SQL
15
ORDER BY order_by_expression
[ COLLATE collation_name ]
[ ASC | DESC ]
[ ,...n ]
[ <offset_fetch> ]
<offset_fetch> ::=
{
OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }
[
FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW |
ROWS } ONLY
]
}
Argumentos
order_by_expression
Especifica uma coluna ou expressão na qual o conjunto de resultados da consulta deve ser
classificado. Uma coluna de classificação pode ser especificada como um nome ou alias de coluna, ou um
inteiro não negativo que representa a posição da coluna na lista de seleção.
Várias colunas de classificação podem ser especificadas. Os nomes de coluna devem ser exclusivos. A
sequência das colunas de classificação na cláusula ORDER BY define a organização do conjunto de resultados
classificado. Ou seja, o conjunto de resultados é classificado pela primeira coluna e então essa lista
ordenada é classificada pela segunda coluna e assim por diante.
SQL
SELECT SCHEMA_NAME(schema_id) AS SchemaName FROM sys.objects
ORDER BY SchemaName; -- correct
SELECT SCHEMA_NAME(schema_id) AS SchemaName FROM sys.objects
ORDER BY SchemaName + ''; -- wrong
COLLATE collation_name
Especifica que a operação ORDER BY deve ser executada de acordo com a ordenação especificada
em collation_name e não de acordo com a ordenação da coluna definida na tabela ou na
exibição. collation_name pode ser um nome de ordenação do Windows ou um nome de ordenação
SQL. Para obter mais informações, consulte Suporte a ordenações e a Unicode.COLLATE é aplicável somente
a colunas do tipo char, varchar, nchar e nvarchar.
ASC | DESC
Define que os valores na coluna especificada devem ser classificados em ordem crescente ou
decrescente. ASC classifica do valor mais baixo para o valor mais alto. DESC classifica do valor mais alto para
16
o valor mais baixo. ASC é a ordem de classificação padrão. Valores nulos são tratados como os menores
valores possíveis.
Aplica-se a: SQL Server 2012 (11.x) até o SQL Server 2017 e o Banco de dados SQL do Azure.
Aplica-se a: SQL Server 2012 (11.x) a SQL Server 2017 e Banco de dados SQL do Azure.
Práticas recomendadas
Evite especificar inteiros na cláusula ORDER BY como representações de posição das colunas na lista de
seleção. Por exemplo, embora uma instrução como SELECT ProductID, Name FROM Production.Production
ORDER BY 2 seja válida, ela não é entendida por outros com tanta facilidade quanto com a especificação do
nome de coluna real. Além disso, as alterações na lista de seleção, como a alteração da ordem das colunas
ou a adição de novas colunas, exigirão a modificação da cláusula ORDER BY para evitar resultados
inesperados.
Em uma instrução SELECT TOP (N), sempre use uma cláusula ORDER BY. Essa é a única forma de indicar
de maneira previsível as linhas que são afetadas por TOP.
Interoperabilidade
Quando usada com uma instrução SELECT…INTO para inserir linhas de outra origem, a cláusula ORDER
BY não garante que as linhas sejam inseridas na ordem especificada.
O uso de OFFSET e FETCH em uma exibição não altera a propriedade updateability da exibição.
17
Limitações e Restrições
Não há um limite para o número de colunas na cláusula ORDER BY; porém, o tamanho total das
colunas especificado em uma cláusula ORDER BY não pode exceder 8.060 bytes.
As colunas do tipo ntext, text, image, geography, geometry e XML não podem ser usadas em uma
cláusula ORDER BY.
Nem um inteiro nem uma constante podem ser especificados quando order_by_expressionaparece em
uma função de classificação.
Se um nome de tabela tiver um alias na cláusula FROM, apenas o nome do alias poderá ser utilizado
para qualificar suas colunas na cláusula ORDER BY.
Os nomes e aliases de coluna especificados na cláusula ORDER BY deverão ser definidos na lista de
seleção, se a instrução SELECT contiver uma das seguintes cláusulas ou dos seguintes operadores:
operador UNION
operador EXCEPT
operador INTERSECT
SELECT DISTINCT
Além disso, quando a instrução incluir um operador UNION, EXCEPT ou INTERSECT, os nomes ou
aliases de coluna precisarão ser especificados na lista de seleção da primeira consulta (do lado esquerdo).
Em uma consulta que usa operadores UNION, EXCEPT ou INTERSECT, ORDER BY é permitida somente
ao final da instrução. Essa restrição aplica-se apenas ao especificar UNION, EXCEPT e INTERSECT em uma
consulta de nível superior e não em uma subconsulta. Consulte a seção de Exemplos a seguir.
Não há suporte para OFFSET e FETCH exibições indexadas ou em uma exibição definida usando a
cláusula de CHECK OPTION.
OFFSET e FETCH podem ser usadas em qualquer consulta que permita TOP e ORDER BY, com as
seguintes limitações:
18
É recomendável usar as cláusulas OFFSET e FETCH em vez da cláusula TOP para implementar uma
solução de paginação de consulta e limitar o número de linhas enviadas a um aplicativo cliente.
O uso de OFFSET e FETCH como solução de paginação exige a execução da consulta uma vez para cada
"página" de dados retornados para o aplicativo cliente. Por exemplo, para retornar os resultados de uma
consulta em incrementos de 10 linhas, você deve executar a consulta uma vez para retornar as linhas 1 a 10,
depois executar a consulta novamente para retornar as linhas 11 a 20 e assim por diante. Cada consulta é
independente e elas não são relacionadas entre si. Isso significa que, diferentemente de usar um cursor no
qual a consulta é executada uma vez e o estado é mantido no servidor, o aplicativo cliente é responsável
para controlar o estado. Para obter resultados estáveis entre solicitações de consulta que usam OFFSET e
FETCH, as seguintes condições devem ser atendidas:
1. Os dados subjacentes que são usados pela consulta não devem ser alterados. Ou seja, as linhas
afetadas pela consulta não são atualizadas ou todas as solicitações de páginas da consulta são
executadas em uma única transação usando isolamento de transação serializável ou de
instantâneo.
2. A cláusula ORDER BY contém uma coluna ou combinação de colunas cuja exclusividade é
garantida.
Consulte o exemplo "Executando várias consultas em uma única transação" na seção de Exemplos
posteriormente neste tópico.
Se planos de execução consistentes forem importantes na sua solução de paginação, considere o uso
da dica de consulta OPTIMIZE FOR para os parâmetros OFFSET e FETCH. Consulte "Especificado expressões
para valores de OFFSET e FETCH" na seção de Exemplos posteriormente neste tópico.
Exemplos
Sintaxe básica
Os exemplos nesta seção demonstram a funcionalidade básica da cláusula ORDER BY usando a sintaxe
mínima necessária.
O exemplo a seguir classifica o conjunto de resultados pela coluna numérica ProductID. Como não foi
especificada nenhuma ordem de classificação específica, o padrão (ordem crescente) é usado.
SQL
USE AdventureWorks2012;
GO
SELECT ProductID, Name FROM Production.Product
WHERE Name LIKE 'Lock Washer%'
19
ORDER BY ProductID;
O exemplo a seguir classifica o conjunto de resultados por uma coluna que não está incluída na lista de
seleção, mas que foi definida na tabela especificada na cláusula FROM.
SQL
USE AdventureWorks2012;
GO
SELECT ProductID, Name, Color
FROM Production.Product
ORDER BY ListPrice;
O exemplo a seguir especifica o alias de coluna SchemaName como a coluna da ordem de classificação.
SQL
USE AdventureWorks2012;
GO
SELECT name, SCHEMA_NAME(schema_id) AS SchemaName
FROM sys.objects
WHERE type = 'U'
ORDER BY SchemaName;
O exemplo a seguir usa uma expressão como a coluna de classificação. A expressão é definida usando a
função DATEPART para classificar o conjunto de resultados pelo ano no qual os funcionários foram
contratados.
SQL
USE AdventureWorks2012;
GO
SELECT BusinessEntityID, JobTitle, HireDate
FROM HumanResources.Employee
ORDER BY DATEPART(year, HireDate);
O exemplo a seguir classifica o conjunto de resultados pela coluna numérica ProductID na ordem
decrescente.
SQL
USE AdventureWorks2012;
GO
SELECT ProductID, Name FROM Production.Product
WHERE Name LIKE 'Lock Washer%'
20
ORDER BY ProductID DESC;
O exemplo a seguir classifica o conjunto de resultados pela coluna Name na ordem crescente. Os
caracteres são classificados em ordem alfabética e não em ordem numérica. Ou seja, 10 é tem uma
classificação anterior a 2.
SQL
USE AdventureWorks2012;
GO
SELECT ProductID, Name FROM Production.Product
WHERE Name LIKE 'Lock Washer%'
ORDER BY Name ASC ;
O exemplo a seguir classifica o conjunto de resultados por duas colunas. O conjunto de resultados da
consulta é classificado primeiro na ordem crescente pela coluna FirstName e, em seguida, na ordem
decrescente pela coluna LastName.
SQL
USE AdventureWorks2012;
GO
SELECT LastName, FirstName FROM Person.Person
WHERE LastName LIKE 'R%'
ORDER BY FirstName ASC, LastName DESC ;
O exemplo a seguir mostra como a especificação de uma ordenação na cláusula ORDER BY pode alterar
a ordem na qual os resultados da consulta são retornados. É criada uma tabela que contém uma coluna
definida usando uma ordenação sem diferenciação de maiúsculas e minúsculas, nem de acentos. Os valores
são inseridos com várias diferenças de maiúsculas e minúsculas e de acentos. Como não foi especificado
uma ordenação na cláusula ORDER BY, a primeira consulta usa a ordenação da coluna ao classificar os
valores. Na segunda consulta, uma ordenação com diferenciação de maiúsculas e minúsculas e de assentos
é especificada na cláusula ORDER BY, o que altera a ordem na qual as linhas são retornadas.
SQL
USE tempdb;
GO
CREATE TABLE #t1 (name nvarchar(15) COLLATE Latin1_General_CI_AI)
GO
INSERT INTO #t1 VALUES(N'Sánchez'),(N'Sanchez'),(N'sánchez'),(N'sanchez');
-- This query uses the collation specified for the column 'name' for sorting.
SELECT name
FROM #t1
ORDER BY name;
-- This query uses the collation specified in the ORDER BY clause for
sorting.
21
SELECT name
FROM #t1
ORDER BY name COLLATE Latin1_General_CS_AS;
O exemplo a seguir usa a expressão CASE em uma cláusula ORDER BY para determinar
condicionalmente a ordem de classificação das linhas com base em um determinado valor de coluna. No
primeiro exemplo, é avaliado o valor da coluna SalariedFlag da
tabela HumanResources.Employee. Funcionários que têm o SalariedFlag definido como 1 são retornados
pelo BusinessEntityID em ordem decrescente. Funcionários que têm o SalariedFlag definido como 0 são
retornados pelo BusinessEntityID em ordem crescente. No segundo exemplo, o conjunto de resultados será
ordenado pela coluna TerritoryName quando a coluna CountryRegionName for igual a 'United States' e
por CountryRegionName para todas as outras linhas.
SQL
SELECT BusinessEntityID, SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;
GO
SQL
SELECT BusinessEntityID, LastName, TerritoryName, CountryRegionName
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL
ORDER BY CASE CountryRegionName WHEN 'United States' THEN TerritoryName
ELSE CountryRegionName END;
O exemplo as seguir usa a cláusula ORDER BY nas funções de classificação ROW_NUMBER, RANK,
DENSE_RANK e NTILE.
SQL
USE AdventureWorks2012;
GO
SELECT p.FirstName, p.LastName
,ROW_NUMBER() OVER (ORDER BY a.PostalCode) AS "Row Number"
,RANK() OVER (ORDER BY a.PostalCode) AS "Rank"
,DENSE_RANK() OVER (ORDER BY a.PostalCode) AS "Dense Rank"
,NTILE(4) OVER (ORDER BY a.PostalCode) AS "Quartile"
,s.SalesYTD, a.PostalCode
FROM Sales.SalesPerson AS s
INNER JOIN Person.Person AS p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a
ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL AND SalesYTD <> 0;
22
Limitando o número de linhas retornadas
Os exemplos as seguir usam OFFSET e FETCH para limitar o número de linhas retornadas por uma consulta.
Aplica-se a: SQL Server 2012 (11.x) a SQL Server 2017 e Banco de dados SQL do Azure.
O exemplo a seguir especifica uma constante inteira como o valor das cláusulas OFFSET e FETCH.A
primeira consulta retorna todas as linhas classificadas pela coluna DepartmentID. Compare os resultados
retornados por essa consulta com os resultados das duas consultas seguintes. A próxima consulta usa a
cláusula OFFSET 5 ROWS para ignorar as cinco primeiras linhas e retornar todas as linhas restantes. A
consulta final usa a cláusula OFFSET 0 ROWS para iniciar com a primeira linha e depois usa FETCH NEXT 10
ROWS ONLY para limitar as linhas retornadas a 10 linhas do conjunto de resultados classificado.
SQL
USE AdventureWorks2012;
GO
-- Return all rows sorted by the column DepartmentID.
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
ORDER BY DepartmentID;
-- Skip the first 5 rows from the sorted result set and return all remaining
rows.
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
ORDER BY DepartmentID OFFSET 5 ROWS;
-- Skip 0 rows and return only the first 10 rows from the sorted result set.
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
ORDER BY DepartmentID
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY;
SQL
USE AdventureWorks2012;
GO
-- Specifying variables for OFFSET and FETCH values
DECLARE @StartingRowNumber tinyint = 1
, @FetchRows tinyint = 8;
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
ORDER BY DepartmentID ASC
OFFSET @StartingRowNumber ROWS
FETCH NEXT @FetchRows ROWS ONLY;
23
C. Especificando expressões para valores de OFFSET e FETCH
SQL
USE AdventureWorks2012;
GO
O exemplo a seguir usa uma subconsulta escalar de constante para definir o valor para a cláusula FETCH. A
subconsulta retorna um único valor da coluna PageSize da tabela dbo.AppSettings.
SQL
-- Specifying a constant scalar subquery
USE AdventureWorks2012;
GO
CREATE TABLE dbo.AppSettings (AppSettingID int NOT NULL, PageSize int NOT
NULL);
GO
INSERT INTO dbo.AppSettings VALUES(1, 10);
GO
DECLARE @StartingRowNumber tinyint = 1;
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
ORDER BY DepartmentID ASC
OFFSET @StartingRowNumber ROWS
FETCH NEXT (SELECT PageSize FROM dbo.AppSettings WHERE AppSettingID = 1)
ROWS ONLY;
O exemplo a seguir mostra um método de implementação de uma solução de paginação que assegura que
sejam retornados resultados estáveis em todas as solicitações da consulta. A consulta é executada em uma
única transação usando o nível de isolamento do instantâneo e a coluna especificada na cláusula ORDER BY
assegura a exclusividade da coluna.
24
SQL
USE AdventureWorks2012;
GO
-- Ensure the database can support the snapshot isolation level set for the query.
IF (SELECT snapshot_isolation_state FROM sys.databases WHERE name =
N'AdventureWorks2012') = 0
ALTER DATABASE AdventureWorks2012 SET ALLOW_SNAPSHOT_ISOLATION ON;
GO
-- Create the condition to stop the transaction after all rows have been returned.
WHILE (SELECT COUNT(*) FROM HumanResources.Department) >= @StartingRowNumber
BEGIN
Quando uma consulta usa os operadores UNION, EXCEPT ou INTERSECT, a cláusula ORDER BY deve ser
especificada no final da instrução e os resultados das consultas combinadas são classificados. O exemplo as
seguir retorna todos os produtos que são vermelhos ou amarelos e classifica essa lista combinada pela
coluna ListPrice.
SQL
USE AdventureWorks2012;
GO
SELECT Name, Color, ListPrice
FROM Production.Product
WHERE Color = 'Red'
-- ORDER BY cannot be specified here.
UNION ALL
SELECT Name, Color, ListPrice
FROM Production.Product
WHERE Color = 'Yellow'
ORDER BY ListPrice ASC;
25
Cláusula FROM mais JOIN, APPLY, PIVOT
DELETE
UPDATE
SELECT
A cláusula FROM geralmente é necessária na instrução SELECT. A exceção é quando nenhuma coluna
de tabela é listada e os únicos itens listados são literais ou variáveis ou expressões aritméticas.
Este artigo também descreve as seguintes palavras-chave que podem ser usadas na cláusula FROM:
JOIN
APPLY
PIVOT
Sintaxe
SQL
-- Syntax for SQL Server and Azure SQL Database
<joined_table> ::=
{
<table_source> <join_type> <table_source> ON <search_condition>
| <table_source> CROSS JOIN <table_source>
| left_table_source { CROSS | OUTER } APPLY right_table_source
| [ ( ] <joined_table> [ ) ]
}
<join_type> ::=
26
[ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } [ <join_hint> ] ]
JOIN
<pivoted_table> ::=
table_source PIVOT <pivot_clause> [ [ AS ] table_alias ]
<pivot_clause> ::=
( aggregate_function ( value_column [ [ , ]...n ])
FOR pivot_column
IN ( <column_list> )
)
<unpivoted_table> ::=
table_source UNPIVOT <unpivot_clause> [ [ AS ] table_alias ]
<unpivot_clause> ::=
( value_column FOR pivot_column IN ( <column_list> ) )
<column_list> ::=
column_name [ ,...n ]
<system_time> ::=
{
AS OF <date_time>
| FROM <start_date_time> TO <end_date_time>
| BETWEEN <start_date_time> AND <end_date_time>
| CONTAINED IN (<start_date_time> , <end_date_time>)
| ALL
}
<date_time>::=
<date_time_literal> | @date_time_variable
<start_date_time>::=
<date_time_literal> | @date_time_variable
<end_date_time>::=
<date_time_literal> | @date_time_variable
Argumentos
<table_source>
Especifica uma tabela, exibição, variável de tabela ou origem de tabela derivada, com ou sem um alias,
a ser usada na instrução Transact-SQL. Até 256 origens da tabela podem ser usadas em uma instrução,
embora o limite varie de acordo com a memória disponível e a complexidade de outras expressões na
consulta. Consultas individuais podem não aceitar até 256 origens de tabela.
Observação
O desempenho da consulta pode ser prejudicado com um grande número de tabelas referenciadas em
uma consulta. O tempo de compilação e otimização também é afetado por outros fatores. Esses fatores
incluem a presença de índices e exibições indexadas em cada <table_source> e o tamanho de
<select_list> na instrução SELECT.
27
A ordem de origens de tabela após a palavra-chave FROM não afeta o conjunto de resultados que é
retornado. O SQL Server retorna erros quando aparecem nomes duplicados na cláusula FROM.
table_or_view_name
É o nome de uma tabela ou exibição.
Se a tabela ou exibição existir em outro banco de dados na mesma instância do SQL Server, use um
nome totalmente qualificado no formato database.schema.object_name.
Se a tabela ou exibição existir fora da instância do SQL Server, use um nome de quatro partes no
formato linked_server.catalog.schema.object. Para obter mais informações, consulte sp_addlinkedserver
(Transact-SQL). Um nome de quatro partes que é construído por meio da função OPENDATASOURCE como a
parte do servidor no nome também pode ser usado para especificar a origem da tabela remota. Quando
OPENDATASOURCE é especificado, database_name e schema_name podem não se aplicar a todas as fontes
de dados e podem estar sujeitos às funcionalidades do Provedor OLE DB que acessa o objeto remoto.
[AS] table_alias
É um alias para table_source que pode ser usado por conveniência ou para distinguir uma tabela ou
exibição em uma autojunção ou subconsulta. Em geral, um alias é um nome de tabela abreviado usado para
referência a colunas específicas das tabelas em uma junção. Se o nome da coluna existir em mais de uma
tabela na junção, o SQL Server exigirá que ele seja qualificado por um nome de tabela, nome de exibição ou
alias. O nome da tabela não poderá ser usado se um alias estiver definido.
Quando uma tabela derivada, um conjunto de linhas, uma função com valor de tabela ou uma cláusula
de operador (como PIVOT ou UNPIVOT) é usado, o table_alias obrigatório no final da cláusula é o nome da
tabela associado para todas as colunas retornadas, incluindo colunas de agrupamento.
WITH (<table_hint> )
Especifica que o otimizador de consulta use uma estratégia de otimização ou bloqueio com esta tabela
e para esta instrução. Para obter mais informações, consulte Dicas de tabela (Transact-SQL).
rowset_function
Aplica-se a: SQL Server 2008 a SQL Server 2017 e Banco de Dados SQL.
Especifica uma das funções de conjunto de linhas, como OPENROWSET, que retorna um objeto que
pode ser usado no lugar de uma referência de tabela. Para obter mais informações sobre uma lista de
funções de conjunto de linhas, consulte Funções de conjunto de linhas (Transact-SQL).
O uso das funções OPENROWSET e OPENQUERY para especificar que um objeto remoto depende dos
recursos do provedor OLE DB que acessa o objeto.
bulk_column_alias
Aplica-se a: SQL Server 2008 a SQL Server 2017 e Banco de Dados SQL.
É um alias opcional para substituir um nome de coluna no conjunto de resultados. Os aliases de coluna
são permitidos somente em instruções SELECT que usam a função OPENROWSET com a opção BULK. Ao
usar bulk_column_alias, especifique um alias para cada coluna da tabela na mesma ordem que as colunas
no arquivo.
Observação
28
Este alias substitui o atributo NAME nos elementos COLUMN de um arquivo de formato XML, se houver.
user_defined_function
Especifica uma função com valor de tabela.
OPENXML <openxml_clause>
Aplica-se a: SQL Server 2008 a SQL Server 2017 e Banco de Dados SQL.
Fornece uma exibição de conjunto de linhas em um documento XML. Para obter mais informações,
consulte OPENXML (SQL Server).
derived_table
É uma subconsulta que recupera linhas do banco de dados. derived_table é usada como entrada para a
consulta externa.
derived _table pode usar o recurso do construtor de valor de tabela Transact-SQL para especificar
várias linhas. Por exemplo, SELECT * FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a,
b);. Para obter mais informações, consulte Construtor de valor de tabela (Transact-SQL).
column_alias
Aplica-se a: SQL Server 2016 (13.x) a SQL Server 2017 e Banco de Dados SQL.
Especifica que uma versão específica dos dados é retornada da tabela temporal especificada e sua
tabela de histórico vinculada com controle de versão do sistema
Cláusula Tablesample
Especifica que uma amostra de dados da tabela é retornada. A amostra pode ser aproximada.Esta
cláusula pode ser usada em qualquer tabela primária ou unida em uma instrução SELECT ou
UPDATE. TABLESAMPLE não pode ser especificado com exibições.
Observação
Quando você usa TABLESAMPLE em bancos de dados atualizados para o SQL Server, o nível de
compatibilidade do banco de dados é definido como 110 ou mais alto, PIVOT não é permitido em uma
consulta CTE (expressão de tabela comum) recursiva. Para obter mais informações, veja Nível de
compatibilidade de ALTER DATABASE (Transact-SQL).
SYSTEM
29
método de amostragem baseado em páginas em que um conjunto aleatório de páginas de uma tabela é
escolhido para a amostra, e todas as linhas dessas páginas são retornadas como subconjunto da amostra.
sample_number
É uma expressão numérica constante exata ou aproximada que representa o percentual ou o número
de linhas. Quando especificado com PERCENT, sample_number é convertido implicitamente em um
valor float; caso contrário, é convertido em bigint. PERCENT é o padrão.
PERCENT
Especifica que um percentual sample_number das linhas da tabela deve ser recuperado da
tabela.Quando PERCENT é especificado, o SQL Server retorna um valor aproximado do percentual
especificado. Quando PERCENT é especificado, a expressão sample_number deve ser avaliada como um
valor de 0 a 100.
ROWS
REPEATABLE
Indica que a amostra selecionada pode ser retornada novamente. Quando for especificado com o
mesmo valor de repeat_seed, o SQL Server retornará o mesmo subconjunto de linhas, desde que não seja
feita nenhuma alteração nas linhas da tabela. Quando for especificado com outro valor de repeat_seed,
o SQL Server provavelmente retornará uma amostra diferente das linhas da tabela. As seguintes ações na
tabela são consideradas alterações: inserir, atualizar, excluir, recompilação do índice ou desfragmentação e
restauração ou anexação do banco de dados.
repeat_seed
É uma expressão de inteiro constante usada pelo SQL Server para gerar um número
aleatório.repeat_seed é bigint. Se repeat_seed não for especificado, SQL Server atribuirá um valor
aleatório.Para um valor repeat_seed específico, o resultado da amostragem será sempre o mesmo se
nenhuma alteração tiver sido aplicada à tabela. A expressão repeat_seed deve ser avaliada como um inteiro
maior que zero.
Cláusula Tablesample
Especifica que uma amostra de dados da tabela é retornada. A amostra pode ser aproximada.Esta
cláusula pode ser usada em qualquer tabela primária ou unida em uma instrução SELECT ou
UPDATE. TABLESAMPLE não pode ser especificado com exibições.
PERCENT
Especifica que um percentual sample_number das linhas da tabela deve ser recuperado da
tabela.Quando PERCENT é especificado, o SQL Data Warehouse retorna um valor aproximado do percentual
30
especificado. Quando PERCENT é especificado, a expressão sample_number precisa ser avaliada como um
valor de 0 a 100.
Tabela unida
Uma tabela unida é um conjunto de resultados que é o produto de duas ou mais tabelas. Para várias
junções, use parênteses para alterar a ordem natural das junções.
Tipo de junção
INNER = Especifica todos os pares de linhas correspondentes retornados. Descarta as linhas não
correspondentes de ambas as tabelas. Quando nenhum tipo de junção é especificado, este é o padrão.
FULL [ OUTER ] = Especifica que uma linha da tabela esquerda ou direita que não atende à condição de
junção seja incluída no conjunto de resultados, e as colunas de saída correspondentes à outra tabela sejam
definidas como NULL. Isso ocorre além de todas as linhas normalmente retornadas por INNER JOIN.
LEFT [ OUTER ] = Especifica que todas as linhas da tabela esquerda que não atendem à condição de
junção sejam incluídas no conjunto de resultados, e as colunas de saída da outra tabela sejam definidas
como NULL além de todas as linhas retornadas pela junção interna.
RIGHT [OUTER] = Especifica que todas as linhas da tabela direita que não atendem à condição de
junção sejam incluídas no conjunto de resultados, e as colunas de saída que correspondem à outra tabela
sejam definidas como NULL, além de todas as linhas retornadas pela junção interna.
Dica de junção
Para o SQL Server e Banco de Dados SQL, especifica que o otimizador de consulta do SQL Serverusa
uma dica de junção, ou um algoritmo de execução, por junção especificada na cláusula FROM da
consulta. Para obter mais informações, consulte Dicas de junção (Transact-SQL).
Para o SQL Data Warehouse e Parallel Data Warehouse, essas dicas de junção se aplicam a junções
INNER em duas colunas incompatíveis com a distribuição. Elas podem melhorar o desempenho da consulta
restringindo a quantidade de movimentação de dados que ocorre durante o processamento da consulta. As
dicas de junção permitidas para o SQL Data Warehousee Parallel Data Warehouse são as seguintes:
REDUCE = Reduz o número de linhas a serem movidas para a tabela no lado direito da junção, a fim de
tornar compatíveis as duas tabelas incompatíveis com a distribuição. A dica REDUCE também é chamada de
uma dica de semijunção.
REPLICATE = Faz com que os valores na coluna de junção da tabela no lado esquerdo da junção sejam
replicados para todos os nós. A tabela à direita é unida à versão replicada dessas colunas.
REDISTRIBUTE = Força duas fontes de dados a serem distribuídas nas colunas especificadas na cláusula
JOIN. Para uma tabela distribuída, o Parallel Data Warehouse executará uma movimentação de ordem
aleatória. Para uma tabela replicada, o Parallel Data Warehouse executará uma movimentação de
corte. Para entender esses tipos de movimentação, consulte a seção "Operações de plano de consulta DMS"
no tópico "Noções básicas sobre planos de consulta" no Documentação de produto do Parallel Data
Warehouse. Essa dica pode melhorar o desempenho quando o plano de consulta usa uma movimentação de
difusão para resolver uma junção incompatível com a distribuição.
31
JOIN = Indica que a operação de junção especificada deve acontecer entre as origens de tabela ou
exibições especificadas.
SQL
SELECT p.ProductID, v.BusinessEntityID
FROM Production.Product AS p
JOIN Purchasing.ProductVendor AS v
ON (p.ProductID = v.ProductID);
Quando o critério especifica colunas, estas não precisam ter o mesmo nome ou o mesmo tipo de
dados; no entanto, se os tipos de dados não forem iguais, eles deverão ser compatíveis ou tipos que o SQL
Server possa converter implicitamente. Se os tipos de dados não puderem ser convertidos implicitamente, o
critério deverá converter o tipo de dados explicitamente usando a função CONVERT.
Poderá haver predicados que envolvam somente uma das tabelas unidas na cláusula ON. Tais
predicados também podem estar na cláusula WHERE da consulta. Embora a presença de tais predicados não
faça diferença para junções INNER, eles podem gerar um resultado diferente quando junções OUTER estão
envolvidas. Isso ocorre porque os predicados na cláusula ON são aplicados à tabela antes da junção, ao
passo que a cláusula WHERE é semanticamente aplicada ao resultado da junção.
Para obter mais informações sobre critérios de pesquisa e predicados, consulte Critério de pesquisa
(Transact-SQL).
CROSS JOIN = Especifica o produto cruzado de duas tabelas. Retorna as mesmas linhas como se
nenhuma cláusula WHERE estivesse especificada em uma junção em estilo antigo que não seja SQL-92.
É necessário especificar CROSS ou OUTER com APPLY. Quando CROSS é especificado, nenhuma linha é
produzida quando a right_table_source é avaliada em uma linha especificada da left_table_source e retorna
um conjunto de resultados vazio.
Quando OUTER é especificado, uma linha é produzida para cada linha da left_table_source, mesmo
quando a right_table_source é avaliada nessa linha e retorna um conjunto de resultados vazio.
left_table_source
É uma origem de tabela conforme a definição no argumento anterior. Para obter mais informações,
consulte a seção Comentários.
right_table_source
É uma origem de tabela conforme a definição no argumento anterior. Para obter mais informações,
consulte a seção Comentários.
Cláusula PIVOT
32
table_source PIVOT <pivot_clause>
Especifica que a table_source é dinamizada com base na pivot_column. table_source é uma tabela ou
uma expressão de tabela. A saída é uma tabela que contém todas as colunas da table_source, exceto
a pivot_column e value_column. As colunas da table_source, exceto a pivot_column e a value_column, são
chamadas as colunas de agrupamento do operador original. Para obter mais informações sobre PIVOT e
UNPIVOT, consulte Usando PIVOT e UNPIVOT.
aggregate_function
É um sistema ou uma função de agregação definida pelo usuário que aceita uma ou mais entradas. A
função de agregação deve ser invariável para valores nulos. Uma função de agregação invariável para
valores nulos não considera valores nulos no grupo enquanto está avaliando o valor de agregação.
value_column
É a coluna de valor do operador PIVOT. Quando usado com UNPIVOT, value_column não pode ser o
nome de uma coluna existente na table_source de entrada.
FOR pivot_column
É a coluna dinâmica do operador PIVOT. pivot_column deve ser de um tipo implícita ou explicitamente
conversível em nvarchar() . Esta coluna não pode ser image ou rowversion.
Quando UNPIVOT é usado, pivot_column é o nome da coluna de saída que é reduzida com base
na table_source. Não pode haver uma coluna em table_source com esse nome.
IN (column_list )
Na cláusula PIVOT, lista os valores na pivot_column que se tornarão os nomes de coluna da tabela de
saída. A lista não pode especificar nomes de coluna já existentes na table_source de entrada que está sendo
dinamizada.
Na cláusula UNPIVOT, lista as colunas na table_source que serão reduzidas a uma única pivot_column.
table_alias
UNPIVOT <unpivot_clause>
Especifica que a tabela de entrada é reduzida com base em várias colunas na column_list a uma única
coluna chamada pivot_column. Para obter mais informações sobre PIVOT e UNPIVOT, consulte Usando
PIVOT e UNPIVOT.
AS OF <date_time>
33
Aplica-se a: SQL Server 2016 (13.x) a SQL Server 2017 e Banco de Dados SQL.
Retorna uma tabela com um único registro para cada linha que contém os valores que foram reais
(atuais) no momento passado especificado. Internamente, uma união é executada entre a tabela temporal e
sua tabela de histórico e os resultados são filtrados para retornar os valores na linha que era válida no ponto
no tempo especificado pelo parâmetro <date_time> . O valor de uma linha é considerado válido se o valor
de system_start_time_column_name é menor ou igual ao valor do parâmetro <date_time> e o valor
de system_end_time_column_name é maior que o valor do parâmetro <date_time> .
Aplica-se a: SQL Server 2016 (13.x) a SQL Server 2017 e Banco de Dados SQL.
Retorna uma tabela com os valores para todas as versões de registro que estavam ativas no intervalo
de tempo especificado, sem levar em conta se eles começaram a estar ativos antes do valor de
parâmetro <start_date_time> para o argumento FROM ou deixaram de estar ativos após o valor de
parâmetro <end_date_time> para o argumento TO. Internamente, uma união é executada entre a tabela
temporal e sua tabela de histórico e os resultados são filtrados para retornar os valores para todas as
versões de linha que estavam ativas a qualquer momento durante o intervalo de tempo especificado. As
linhas que se tornaram ativas exatamente no limite inferior definido pelo ponto de extremidade FROM são
incluídas e as linhas que se tornaram ativas exatamente no limite superior definido pelo ponto de
extremidade TO não são incluídas.
Aplica-se a: SQL Server 2016 (13.x) a SQL Server 2017 e Banco de Dados SQL.
A mesma descrição acima para FROM <start_date_time> TO <end_date_time> é válida, exceto que
ela inclui linhas que se tornaram ativas no limite superior definido pelo ponto de extremidade
<end_date_time>.
Aplica-se a: SQL Server 2016 (13.x) a SQL Server 2017 e Banco de Dados SQL.
Retorna uma tabela com os valores para todas as versões de registro que foram abertas e fechadas
dentro do intervalo de tempo especificado definido por dois valores de data e hora para o argumento
CONTAINED IN. As linhas que se tornaram ativas exatamente no limite inferior ou que deixaram de ser
ativas exatamente no limite superior são incluídas.
ALL
Retorna uma tabela com os valores de todas as linhas da tabela atual e da tabela de histórico.
Remarks
A cláusula FROM aceita a sintaxe SQL-92 para tabelas unidas e derivadas. Sintaxe SQL-92 fornece os
operadores de junção INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER e CROSS.
Há suporte para UNION e JOIN em uma cláusula FROM dentro de exibições e em tabelas derivadas e
subconsultas.
34
Uma autojunção é uma tabela unida a ela mesma. As operações de inserção ou atualização que são
baseadas em uma autojunção seguem a ordem da cláusula FROM.
Usando APPLY
Ambos os operandos à esquerda e à direita do operador APPLY são expressões de tabela. A principal
diferença entre esses operandos é que right_table_source pode usar uma função com valor de tabela que
usa uma coluna da left_table_source como um dos argumentos da função. A left_table_source pode incluir
funções com valor de tabela, mas não pode conter argumentos que são colunas da right_table_source.
O operador APPLY funciona da seguinte maneira para criar a origem de tabela para a cláusula FROM:
2. Combina os conjuntos de resultados que são produzidos para cada linha na avaliação de
right_table_source com a left_table_source executando uma operação UNION ALL.
A pivot_column e a value_column são colunas de agrupamento usadas pelo operador PIVOT. Este
segue o seguinte processo para obter o conjunto de resultados de saída:
1. Executa um GROUP BY em sua input_table nas colunas de agrupamento e produz uma linha de
saída para cada grupo.
2. Gera valores para as colunas da lista de colunas para cada linha de saída da seguinte forma:
35
Server gerará um valor nulo para essa output_column. Se a função de agregação for COUNT
e o subgrupo estiver vazio, será retornado zero (0).
Observação
Os identificadores de coluna na cláusula UNPIVOT seguem a ordenação de catálogo. Para o Banco de
Dados SQL, a ordenação é sempre SQL_Latin1_General_CP1_CI_AS. Para bancos de dados parcialmente
independentes do SQL Server, a ordenação é sempre Latin1_General_100_CI_AS_KS_WS_SC. Se a coluna
for combinada com outras colunas, uma cláusula COLLATE (COLLATE DATABASE_DEFAULT) será
necessária para evitar conflitos.
Permissões
Exemplos
O exemplo a seguir recupera as colunas TerritoryID e Name da tabela SalesTerritory no banco de dados de
exemplo AdventureWorks2012.
SQL
SELECT TerritoryID, Name
FROM Sales.SalesTerritory
ORDER BY TerritoryID ;
SQL
TerritoryID Name
----------- ------------------------------
1 Northwest
2 Northeast
3 Central
4 Southwest
5 Southeast
6 Canada
7 France
8 Germany
9 Australia
10 United Kingdom
(10 row(s) affected)
A transação parcial a seguir mostra como posicionar um bloqueio de tabela compartilhado explícito
em Employee e como ler o índice. O bloqueio é mantido ao longo de toda a transação.
SQL
BEGIN TRAN
SELECT COUNT(*)
FROM HumanResources.Employee WITH (TABLOCK, HOLDLOCK) ;
36
C. Usando a sintaxe SQL-92 CROSS JOIN
O exemplo a seguir retorna o produto cruzado das tabelas Employee e Department no banco de
dados AdventureWorks2012. Uma lista de todas as possíveis combinações de linhas de BusinessEntityID e
todas as linhas de nome de Department é retornada.
SQL
SELECT e.BusinessEntityID, d.Name AS Department
FROM HumanResources.Employee AS e
CROSS JOIN HumanResources.Department AS d
ORDER BY e.BusinessEntityID, d.Name ;
SQL
-- The OUTER keyword following the FULL keyword is optional.
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
FULL OUTER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY p.Name ;
O exemplo a seguir une duas tabelas em ProductID e preserva as linhas não correspondentes da tabela
esquerda. É feita a correspondência da tabela Product com a tabela SalesOrderDetail nas
colunas ProductID em cada tabela. Todos os produtos, ordenados ou não, aparecem no conjunto de
resultados.
SQL
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
LEFT OUTER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY p.Name ;
SQL
-- By default, SQL Server performs an INNER JOIN if only the JOIN
-- keyword is specified.
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
37
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY p.Name ;
O exemplo a seguir une duas tabelas em TerritoryID e preserva as linhas não correspondentes da tabela
direita. É feita a correspondência da tabela SalesTerritory com a tabela SalesPersonna coluna TerritoryID em
cada tabela. Todos os vendedores aparecem no conjunto de resultados, tenham ou não um território
atribuído.
SQL
SELECT st.Name AS Territory, sp.BusinessEntityID
FROM Sales.SalesTerritory AS st
RIGHT OUTER JOIN Sales.SalesPerson AS sp
ON st.TerritoryID = sp.TerritoryID ;
H. Usando dicas de junção HASH e MERGE
Importante
Após uma dica de junção ser especificada, a palavra-chave INNER não é mais opcional e deve ser
explicitamente declarada para a execução de uma INNER JOIN.
SQL
SELECT p.Name AS ProductName, v.Name AS VendorName
FROM Production.Product AS p
INNER MERGE JOIN Purchasing.ProductVendor AS pv
ON p.ProductID = pv.ProductID
INNER HASH JOIN Purchasing.Vendor AS v
ON pv.BusinessEntityID = v.BusinessEntityID
ORDER BY p.Name, v.Name ;
O exemplo a seguir usa uma tabela derivada, uma instrução SELECT após a clausula FROM, para retornar o
nome e o sobrenome de todos os funcionários e as cidades em que moram.
SQL
SELECT RTRIM(p.FirstName) + ' ' + LTRIM(p.LastName) AS Name, d.City
FROM Person.Person AS p
INNER JOIN HumanResources.Employee e ON p.BusinessEntityID = e.BusinessEntityID
INNER JOIN
(SELECT bea.BusinessEntityID, a.City
FROM Person.Address AS a
INNER JOIN Person.BusinessEntityAddress AS bea
ON a.AddressID = bea.AddressID) AS d
ON p.BusinessEntityID = d.BusinessEntityID
ORDER BY p.LastName, p.FirstName;
38
J. Usando TABLESAMPLE para ler dados de uma amostra de linhas em uma tabela
O exemplo a seguir usa TABLESAMPLE na cláusula FROM para retornar aproximadamente 10 por cento de
todas as linhas na tabela Customer.
SQL
SELECT *
FROM Sales.Customer TABLESAMPLE SYSTEM (10 PERCENT) ;
K. Usando APPLY
O seguinte exemplo presume que as seguintes tabelas e função com valor de tabela estejam presentes no
banco de dados:
A função com valor de tabela GetReports retorna a lista de todos os funcionários que se reportam direta ou
indiretamente ao MgrID especificado. O exemplo usa APPLY para retornar todos os departamentos e todos
os funcionários do departamento. Se um departamento em particular não tiver funcionários, não haverá
linhas retornadas para ele.
SQL
SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d
CROSS APPLY dbo.GetReports(d.DeptMgrID) ;
Se desejar que a consulta gere linhas para os departamentos sem funcionários, o que irá gerar valores nulos
para as colunas EmpID, EmpLastName e EmpSalary, use então OUTER APPLY.
SQL
SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d
OUTER APPLY dbo.GetReports(d.DeptMgrID) ;
O exemplo a seguir recupera um instantâneo de todos os planos de consulta residindo no cache de plano,
consultando a exibição de gerenciamento dinâmico sys.dm_exec_cached_plans para recuperar os
identificadores de plano de todas as consultas no cache. Em seguida, o operador CROSS APPLY é
especificado para transmitir o identificador de plano a sys.dm_exec_query_plan. A saída de plano de
execução XML de cada plano atualmente no cache de plano está na coluna query_plan da tabela retornada.
SQL
USE master;
GO
SELECT dbid, object_id, query_plan
FROM sys.dm_exec_cached_plans AS cp
39
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle);
GO
SQL
SELECT DepartmentNumber,
DepartmentName,
ManagerID,
ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME AS OF '2014-01-01'
WHERE ManagerID = 5;
SQL
SELECT DepartmentNumber,
DepartmentName,
ManagerID,
ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME FROM '2013-01-01' TO '2014-01-01'
WHERE ManagerID = 5;
SQL
SELECT DepartmentNumber,
DepartmentName,
ManagerID,
ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME BETWEEN '2013-01-01' AND '2014-01-01'
WHERE ManagerID = 5;
SQL
SELECT DepartmentNumber,
DepartmentName,
ManagerID,
ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME CONTAINED IN ( '2013-01-01', '2014-01-01' )
40
WHERE ManagerID = 5;
O exemplo a seguir usa uma variável em vez de um literal para fornecer os valores de limite de data para a
consulta.
SQL
DECLARE @AsOfFrom datetime2 = dateadd(month,-12, sysutcdatetime());
DECLARE @AsOfTo datetime2 = dateadd(month,-6, sysutcdatetime());
SELECT DepartmentNumber,
DepartmentName,
ManagerID,
ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME FROM @AsOfFrom TO @AsOfTo
WHERE ManagerID = 5;
41