FROM (Transact-SQL)

Especifica as tabelas, exibições, tabelas derivadas e tabelas unidas usadas em instruções DELETE, SELECT e UPDATE. Na instrução SELECT, a cláusula FROM é necessária, exceto quando a lista de seleção contém apenas constantes, variáveis e expressões aritméticas (sem nomes de coluna).

Ícone de vínculo de tópicoConvenções de sintaxe Transact-SQL

Sintaxe

[ FROM { <table_source> } [ ,...n ] ] 
<table_source> ::= 
{
        table_or_view_name [ [ AS ] table_alias ] [ <tablesample_clause> ] 
        [ WITH ( < table_hint > [ [ , ]...n ] ) ] 
    | rowset_function [ [ AS ] table_alias ] 
        [ ( bulk_column_alias [ ,...n ] ) ] 
        | user_defined_function [ [ AS ] table_alias ] ]
    | OPENXML <openxml_clause> 
    | derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ] 
    | <joined_table> 
    | <pivoted_table> 
    | <unpivoted_table>
      | @variable [ [ AS ] table_alias ]
        | @variable.function_call ( expression [ ,...n ] ) [ [ AS ] table_alias ] [ (column_alias [ ,...n ] ) ]
}
<tablesample_clause> ::=
    TABLESAMPLE [SYSTEM] ( sample_number [ PERCENT | ROWS ] ) 
        [ REPEATABLE ( repeat_seed ) ] 

<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> ::= 
    [ { 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 ]

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çãoObservaçã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. Eles incluem a presença de índices e exibições indexadas em cada <table_source> e o tamanho de <select_list> na instrução SELECT.

    A ordem de origens de tabela depois da palavra-chave FROM não afeta o conjunto de resultados 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 banco de dados.esquema.nome_do_objeto.

    Se a tabela ou exibição existir fora da instância do SQL Serverl, use um nome de quatro partes no formato servidor_vinculado.catálogo.esquema.object. Para obter mais informações, consulte sp_addlinkedserver (Transact-SQL). Um nome de quatro partes que é criado usando-se a função OPENDATASOURCE como a parte do servidor no nome também pode ser usado para especificar a origem da tabela remota. Quando OPENDATASOURCE é especificada, database_name e schema_name podem não se aplicar a todas as fontes de dados e podem estar sujeitos aos recursos do provedor OLE DB que acessa o objeto remoto. Para obter mais informações, consulte Consultas distribuídas.

  • [AS] table_alias
    É uma 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 é usada uma tabela derivada, um conjunto de linhas, uma função com valor de tabela ou uma cláusula de operador (como PIVOT ou UNPIVOT), o table_alias necessário no final da cláusula é o nome de 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
    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).

    Usando as funções OPENROWSET e OPENQUERY para especificar que um objeto remoto depende dos recursos do provedor OLE DB que acessa o objeto. Para obter mais informações, consulte Consultas distribuídas.

  • bulk_column_alias
    É 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çãoObservação

    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>
    Fornece uma exibição de conjunto de linhas em um documento XML. Para obter mais informações, consulte OPENXML (Transact-SQL).

  • derived_table
    É uma subconsulta que recupera linhas do banco de dados. A derived_table é usada como entrada para a consulta externa.

    derived_table pode usar o recurso do construtor de valor de tabela do 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
    É um alias opcional para substituir um nome de coluna no conjunto de resultados da tabela derivada. Inclua um alias para cada coluna na lista de seleção e encerre a lista completa de aliases de coluna entre parênteses.

  • <tablesample_clause>
    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, UPDATE ou DELETE. TABLESAMPLE não pode ser especificado com exibições. Para obter mais informações, consulte Limitando conjuntos de resultados utilizando TABLESAMPLE.

    ObservaçãoObservação

    Quando você usa TABLESAMPLE em bancos de dados atualizados para o SQL Server, o nível de compatibilidade do banco de dados deve ser definido como 90 ou um valor superior. Para definir o nível de compatibilidade do banco de dados, consulte Nível de compatibilidade de ALTER DATABASE (Transact-SQL).

  • SYSTEM
    É um método de amostragem dependente de implementação especificado por padrões ISO. No SQL Server, esse é o único método de amostragem disponível e é aplicado por padrão. SYSTEM aplica um 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. Para obter mais informações, consulte Limitando conjuntos de resultados utilizando TABLESAMPLE.

  • 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
    Especifica que, aproximadamente, será recuperado o sample_number de linhas. Quando ROWS é especificado, o SQL Server retorna uma aproximação do número de linhas especificado. Quando ROWS é especificado, a expressão sample_number deve ser avaliada como um valor inteiro maior que zero.

  • REPEATABLE
    Indica que a amostra selecionada pode ser retornada novamente. Quando é especificado com o mesmo valor de repeat_seed , o SQL Server retorna o mesmo subconjunto de linhas, desde que não seja feita nenhuma alteração nas linhas da tabela. Quando for especificado com um valor repeat_seed diferente, o SQL Server provavelmente retornará alguma amostra diferente das linhas da tabela. As seguintes ações na tabela são consideradas alterações: inserção, atualização, exclusão, desfragmentação ou recriação de índice, anexação ou restauração de 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.

  • <joined_table>
    É 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.

  • <join_type>
    Especifica o tipo de operação 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.

  • <join_hint>
    Especifica que o otimizador de consultas do SQL Server use uma dica de junção, ou um algoritmo de execução, para cada consulta especificada na cláusula FROM da consulta. Para obter mais informações, consulte dicas de junção (Transact-SQL).

  • JOIN
    Indica que a operação de junção especificada deve acontecer entre as origens de tabela ou exibições especificadas.

  • ON <search_condition>
    Especifica o critério no qual a junção se baseia. O critério pode especificar qualquer predicado, embora colunas e operadores de comparação sejam freqüentemente usados, por exemplo:

    SELECT p.ProductID, v.VendorID
    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.

  • left_table_source{ CROSS | OUTER } APPLY right_table_source
    Especifica que o right_table_source do operador APPLY é avaliado em cada linha de left_table_source. Essa funcionalidade é útil quando right_table_source contém uma função com valor de tabela que utiliza valores de coluna de left_table_source como um de seus argumentos.

    É necessário especificar CROSS ou OUTER com APPLY. Quando CROSS é especificado, nenhuma linha é criada quando right_table_source é avaliado em uma linha especificada de left_table_source e retorna um conjunto de resultados vazio.

    Quando OUTER é especificado, uma linha é criada para cada linha de left_table_source mesmo quando right_table_source é avaliado nessa linha e retorna um conjunto de resultados vazio.

    Para obter mais informações, consulte a seção Comentários e Usando APPLY.

  • 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.

  • table_source PIVOT <pivot_clause>
    Especifica que table_source é um valor dinâmico com base em pivot_column. table_source é uma tabela ou expressão de tabela. A saída é uma tabela que contém todas as colunas de table_source, exceto pivot_column e value_column. As colunas de table_source, exceto pivot_column e value_column, são chamadas de colunas de agrupamento do operador dinâmico.

    PIVOT executa uma operação de agrupamento na tabela de entrada em relação às colunas de agrupamento e retorna uma linha para cada grupo. Além disso, a saída contém uma coluna para cada valor especificado em column_list que aparece em pivot_column de input_table.

    Para obter mais informações, consulte a seção Comentários e Usando PIVOT e UNPIVOT.

    ObservaçãoObservação

    Quando você usa PIVOT em bancos de dados atualizados para o SQL Server, o nível de compatibilidade do banco de dados deve ser definido como 90 ou um valor superior. Para obter mais informações sobre a definição do nível de compatibilidade do banco de dados, consulte Nível de compatibilidade de ALTER DATABASE (Transact-SQL).

  • 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 agregado.

    A função de agregação de sistema COUNT (*) não é permitida.

  • 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 no table_sourcede entrada.

  • FOR pivot_column
    É a coluna dinâmica do operador PIVOT. pivot_column deve ser de um tipo que possa ser convertido implícita ou explicitamente em nvarchar(). Essa coluna não pode ser image ou rowversion.

    Quando UNPIVOT é usado, pivot_column é o nome da coluna de saída que é restrita a partir de table_source. Não pode haver uma coluna em table_source com esse nome.

  • IN ( column_list )
    Na cláusula PIVOT, lista os valores em 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 no table_source de saída que está sendo dinamizado.

    Na cláusula UNPIVOT, lista as colunas em table_source que serão restritas em um único pivot_column.

  • table_alias
    É o alias da tabela de saída. É necessário especificar pivot_table_alias.

  • UNPIVOT < unpivot_clause >
    Especifica que a tabela de entrada é restrita de várias colunas em column_list em uma única coluna chamada pivot_column.

    Para obter mais informações, consulte a seção Comentários e Usando PIVOT e UNPIVOT.

    ObservaçãoObservação

    Quando você usa UNPIVOT em bancos de dados atualizados para o SQL Server, o nível de compatibilidade do banco de dados deve ser definido como 90 ou um valor superior. Para definir o nível de compatibilidade do banco de dados, consulte Nível de compatibilidade de ALTER DATABASE (Transact-SQL).

Comentários

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.

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.

Versões anteriores do SQL Server oferecem suporte à definição de junções externas que usam operadores *= and =* na cláusula WHERE. O SQL Server versão 7.0 oferece suporte ao padrão ISO. Isso fornece operadores de junção na cláusula FROM. Quando o nível de compatibilidade do banco de dados é definido como 90 ou mais, os operadores de junção externa (*= e =*) não têm suporte.

Como o SQL Server considera as estatísticas de distribuição e cardinalidade de servidores vinculados que fornecem estatísticas de distribuição de coluna, a dica de junção REMOTE não é necessária para impor a avaliação de uma junção remotamente. O processador de consulta do SQL Server considera estatísticas remotas e determina se uma estratégia da junção remota é apropriada. A dica de junção REMOTE é útil para provedores que não fornecem estatísticas de distribuição de coluna. Para obter mais informações, consulte Requisitos de estatísticas de distribuição para provedores OLE DB.

Para obter mais informações sobre como trabalhar com junções, consulte Conceitos básicos de junção e Usando junções.

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 utiliza uma coluna de left_table_source como um dos argumentos da função. left_table_source pode incluir funções com valor de tabela, mas não conter argumentos que sejam colunas de right_table_source.

O operador APPLY funciona da seguinte maneira para criar a origem de tabela para a cláusula FROM:

  1. Avalia right_table_source em cada linha de left_table_source para criar conjuntos de linhas.

    Os valores em right_table_source dependem de left_table_source. right_table_source pode ser representado aproximadamente desta forma: TVF(left_table_source.row), onde TVF é uma função com valor de tabela.

  2. Combina os conjuntos de resultados que são criados para cada linha na avaliação de right_table_source com left_table_source executando uma operação UNION ALL.

    A lista de colunas criada pelo resultado do operador APPLY é o conjunto de left_table_source combinado à lista de colunas de right_table_source.

Usando PIVOT e UNPIVOT

pivot_column e 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 seu input_table nas colunas de agrupamento e cria uma linha de saída para cada grupo.

    As colunas de agrupamento na linha de saída obtêm os valores de coluna correspondentes para o grupo em input_table.

  2. Gera valores para as colunas da lista de colunas para cada linha de saída da seguinte forma:

    1. Agrupando as linhas geradas em GROUP BY na etapa anterior em pivot_column.

      Para cada coluna de saída em column_list, selecionando um subgrupo que satisfaça a condição:

      pivot_column = CONVERT(<data type of pivot_column>, 'output_column')

    2. aggregate_function é avaliado em value_column nesse subgrupo e seu resultado é retornado como o valor do output_column correspondente. Se o subgrupo estiver vazio, o SQL Server gerará um valor nulo para esse output_column. Se a função de agregação for COUNT e o subgrupo estiver vazio, será retornado zero (0).

Para obter mais informações, consulte Usando PIVOT e UNPIVOT.

Permissões

Requer as permissões para a instrução DELETE, SELECT ou UPDATE.

Exemplos

A. Usando uma cláusula FROM simples

O exemplo a seguir recupera as colunas TerritoryID e Name da tabela SalesTerritory no banco de dados de exemplo AdventureWorks.

USE AdventureWorks ;
GO
SELECT TerritoryID, Name
FROM Sales.SalesTerritory
ORDER BY TerritoryID ;

Conjunto de resultados.

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)

B. Usando as dicas de otimizador TABLOCK e HOLDLOCK

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.

USE AdventureWorks ;
GO
BEGIN TRAN
SELECT COUNT(*) 
FROM HumanResources.Employee WITH (TABLOCK, HOLDLOCK) ;

C. Usando a sintaxe SQL-92 CROSS JOIN

O exemplo a seguir retorna o produto cruzado das tabelas Employee e Department. É retornada uma lista de todas as possíveis combinações de linhas de EmployeeID e todas as linhas de nome de Department .

USE AdventureWorks ;
GO
SELECT e.EmployeeID, d.Name AS Department
FROM HumanResources.Employee AS e
CROSS JOIN HumanResources.Department AS d
ORDER BY e.EmployeeID, d.Name ;

D. Usando a sintaxe SQL-92 FULL OUTER JOIN

O exemplo a seguir retorna o nome do produto e quaisquer ordens de venda correspondentes na tabela SalesOrderDetail. Ele também retorna as ordens de venda que não têm produtos listados na tabela Product, bem como produtos com uma ordem de venda diferente daquela listada na tabela Product.

USE AdventureWorks ;
GO
-- 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
WHERE p.ProductID IS NULL OR sod.ProductID IS NULL
ORDER BY p.Name ;

E. Usando a sintaxe SQL-92 LEFT OUTER JOIN

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.

USE AdventureWorks ;
GO
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 ;

F. Usando a sintaxe SQL-92 INNER JOIN

O exemplo a seguir retorna todos os nomes de produtos e IDs de ordens de venda.

USE AdventureWorks ;
GO
-- 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
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY p.Name ;

G. Usando a sintaxe SQL-92 RIGHT OUTER JOIN

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 SalesPerson na coluna TerritoryID em cada tabela. Todos os vendedores aparecem no conjunto de resultados, tenham ou não um território atribuído.

USE AdventureWorks ;
GO
SELECT st.Name AS Territory, sp.SalesPersonID
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

O exemplo a seguir executa uma junção de três tabelas entre as tabelas Product, ProductVendor e Vendor para criar uma lista de produtos e seus fornecedores. O otimizador de consulta une Product e ProductVendor (p e pv) usando uma junção MERGE. Em seguida, os resultados da junção MERGE de Product e ProductVendor (p e pv) são unidos por HASH à tabela Vendor para criar (p e pv) e v.

Observação importanteImportante

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.

USE AdventureWorks ;
GO
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.VendorID = v.VendorID
ORDER BY p.Name, v.Name ;

I. Usando uma tabela derivada

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.

USE AdventureWorks ;
GO
SELECT RTRIM(c.FirstName) + ' ' + LTRIM(c.LastName) AS Name,
 d.City
FROM Person.Contact AS c
INNER JOIN HumanResources.Employee e ON c.ContactID = e.ContactID 
INNER JOIN
   (SELECT ea.AddressID, ea.EmployeeID, a.City 
    FROM Person.Address AS a
    INNER JOIN HumanResources.EmployeeAddress AS ea
    ON a.AddressID = ea.AddressID) AS d
ON e.EmployeeID = d.EmployeeID
ORDER BY c.LastName, c.FirstName;

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 da tabela Customer no banco de dados AdventureWorks.

USE AdventureWorks ;
GO
SELECT *
FROM Sales.Customer TABLESAMPLE SYSTEM (10 PERCENT) ;

K. Usando APPLY

O seguinte exemplo presume que as tabelas com o esquema a seguir estão presentes no banco de dados:

  • Departments: DeptID, DivisionID, DeptName, DeptMgrID

  • EmpMgr: MgrID, EmpID

  • Employees: EmpID, EmpLastName, EmpFirstName, EmpSalary

Há também uma função com valor de tabela, GetReports(MgrID) que retorna a lista de todos os funcionários (EmpID, EmpLastName, EmpSalary) subordinados 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.

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.

SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d OUTER APPLY dbo.GetReports(d.DeptMgrID) ;

L. Usando PIVOT e UNPIVOT

O exemplo a seguir retorna o número de ordens de compra inseridas pelas IDs de funcionário 164, 198, 223, 231 e 233, categorizadas pela ID de fornecedor.

USE AdventureWorks;
GO
SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5
FROM 
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) AS p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [164], [198], [223], [231], [233] )
) AS pvt
ORDER BY VendorID;

Aqui está um conjunto de resultados parcial:

VendorID    Emp1        Emp2        Emp3        Emp4        Emp5

----------------------------------------------------------------

1           4           3           5           4           4

2           4           1           5           5           5

3           4           3           5           4           4

4           4           2           5           5           4

5           5           1           5           5           5

Para que a tabela não seja mais dinâmica, suponha que o conjunto de resultados gerado no exemplo anterior seja armazenado como pvt. A consulta será semelhante à do exemplo a seguir.

--Create the table and insert values as portrayed in the previous example.
CREATE TABLE dbo.pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int);
GO
-- Insert 5 rows into the table.
INSERT INTO dbo.pvt VALUES (1,4,3,5,4,4),(2,4,1,5,5,5),(3,4,3,5,4,4),
                           (4,4,2,5,5,4),(5,5,1,5,5,5);
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM 
    (SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
    FROM dbo.pvt) AS p
UNPIVOT
    (Orders FOR Employee IN 
        (Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt;
GO

Aqui está um conjunto de resultados parciais:

VendorID    Employee    Orders

------------------------------

1           Emp1        4

1           Emp2        3

1           Emp3        5

1           Emp4        4

1           Emp5        4

2           Emp1        4

2           Emp2        1

2           Emp3        5

2           Emp4        5

2           Emp5        5