MCDBA Brasil


  • Home
  • Sobre
  • Contato

Livros





Links Rápidos

SQL Server Builds (All Versions/Editions)


Download SQL Server 2017 (trial)


SQL Server 2017 Feature Pack


SQL Server 2016 Feature Pack


Cumulative Update SQL Server 2017 builds


Cumulative Update SQL Server 2016 builds


Cumulative Update SQL Server 2014 builds


Cumulative Update SQL Server 2012 builds


SQL Server 2005/2008 Samples Databases


Documentando o Servidor SQL Server


Analisando a Performance do Servidor-CheckList


Virtual PASS PT


Faça parte do maior virtual chapter do PASS com conteúdos técnicos em Português sobre SQL Server.

Todos os meses um evento Online para você! Acompanhe aqui os WebCasts já agendados

Sindicalize seu blog ou site ao VirtualPASSPT

SQL Server Blogs

SQL Server Query Processing Team


SQL Programmability & API Development Team


SQL Server Manageability Team


Latin America Support Team


Database + Disk + Performance


Microsoft SQL Server Support


SQL CLR Team


SQL Query Optimization Team


SQL 2005 Code Samples


SQL Server Express Team


SQL SMO Samples


SQL Storage Engine Team


SQL CAT Team


SQL Protocols Team


PSS SQL Server Engineers


Slava Oks on SQLOS


Ken Henderson’s blog


LUTI@Microsoft Blog


kimberly L. Trip’s blog


Fernando Garcia Blog

Dica da Semana

Trabalhando com Subquery

por Nilton Pinheiro dezembro 28, 2004 Nenhum comentário

Este primeiro exemplo demonstra como podemos colocar uma subquery no lugar de uma coluna que será retornada na instrução SELECT:


SELECT C1 , ( SELECT C2 FROM Tabela2 ) AS C2 , C3
FROM Tabela1


No exemplo acima, as coluna C1 e C3 pertencem à Tabela1 e o campo C2 é um campo calculado através de uma subquery. A subquery obtém o campo C2 da Tabela2.


Aqui já podemos observar alguns pontos importantes:


– O primeiro deles é que sempre devemos colocar uma subquery entre parênteses, pois assim o SQL Server consegue saber que estamos nos referindo a uma subquery.


– Outro ponto importante é que mesmo se a Tabela2 (a que está sendo utilizada na subquery) possuir mais de um campo, somente poderemos retornar um campo, pois a query mais externa somente irá receber o conteúdo de um campo.


– Também podemos perceber que não correlacionamos de nenhuma maneira a Tabela2 com a Tabela1.


Também podemos utilizar o resultado de uma subquery na cláusula WHERE da instrução SELECT como no exemplo abaixo:


SELECT ProductName, QuantityPerUnit
FROM  Products
WHERE UnitPrice = ( SELECT MAX(UnitPrice) FROM Products )


Primeiramente o que a instrução SELECT mais interna (Subquery) faz é retornar o preço máximo  de todos o produtos da tabela Products,  através da função de agregação MAX(). Feito isto, este valor é comparado com todos os produtos e somente aqueles que possuírem o valor máximo serão retornados pela query mais externa.


Com as subquery’s também podemos retornar uma lista de valores, dependendo de qual operador é utilizado.  Veja alguns exemplos:


/* Aqui somente é retornado os clientes que fizeram compras antes da data atual */
SELECT CompanyName,ContactName FROM customers
WHERE CustomerID IN (SELECT CustomerID from orders WHERE OrderDate < GETDATE())


/* Aqui é retornado todos os clientes que já fizeram algum pedido.*/
SELECT CompanyName,ContactName FROM customers
WHERE EXISTS (SELECT CustomerID from orders)


Para os exemplos vistos até agora não nos preocupamos em correlacionar as tabelas que são utilizadas tanto na query mais interna (subquery)  como na mais externa (a query final). Para fazer isto, devemos primeiramente dar um alias para cada tabela e fazer a relação entre estes alias na subquery pois os alias da query mais externa são “enxergados” na query mais interna. Exemplo:


SELECT P.PED_COD , P.PED_DATA  , P.COD_CLI ,
FROM PEDIDO AS P
WHERE P.COD_CLI
IN ( SELECT C.COD_CLI  FROM CLIENTE C WHERE P.COD_CLI = C.COD_CLI )


SELECT ShipName,ShippedDate FROM orders O
WHERE CustomerID IN (SELECT CustomerID FROM Customers C WHERE O.CustomerID=C.CustomerID)


No exemplo acima estamos filtrando a tabela Orders de acordo com a relação feita através da coluna CustomerID tanto da tabela Orders como da tabela Customers. Perceba que utilizamos os alias O e C para identificar as tabelas, pois ambas possuem uma coluna CustomerID.


Agora observem a query abaixo:


SELECT OrderID,OrderDate, CustomerID,
(SELECT CompanyName FROM Customers C WHERE O.CustomerID=C.CustomerID)AS CompanyName
FROM orders O


Nesta subquery estamos retornando o campo CompanyName da tabela Customers. Porém, não estamos filtrando a tabela Orders. Desse modo, se houver algum CustomerID na tabela Orders que não se encontre na tabela Customers o valor NULL será retornado para o campo CompanyName calculado através da subquery.


Alguns detalhes quando utilizarmos subquery’s:


1. Sempre feche as subquey’s com parênteses para que as mesmas funcionem corretamente


2. Subquery’s não podem trabalhar com colunas quem contém o tipo de dados TEXT ou IMAGE. Uma idéia é converter estes dados para outro tipo (como VARCHAR ) através das funções CONVERT() ou CAST() e depois retorná-los na subquery. Exemplo:


SELECT COD, ( SELECT CAST( TXT AS VARCHAR )  FROM BLOB ) AS X
FROM BLOB


3. Sempre que possível procure montar a Subquery antes de colocá-las na instrução SELECT final. Isto ajuda a dividir uma instrução SELECT complexa em pequenos passos. Após obter a subquery correta, coloque-a na query oficial lembrando sempre que para cada registro da query mais externa, a subquery vai ser executada uma vez.


4. Caso precisar correlacionar a subquery interna com a query externa e tanto a query como a subquery utilizarem a mesma tabela, procure colocar um alias para a tabela diferente em cada uma. Por exemplo:


SELECT T1A.C3,
( SELECT T1B.C3 FROM TABELA1 AS T1B WHERE T1A.C1 = T1B.C2 ) AS CALCULADO
FROM TABELA1 AS T1A


5. Quando a instrução SELECT que possuir a subquery ficar muito grande, pense em criar uma view. Desta forma a complexidade da query ficará encapsulada e o usuário final somente utilizará a view.


6. Subquery’s geralmente podem ser convertidas em JOINS. Por exemplo:


SELECT * FROM Orders
WHERE CustomerID IN (SELECT CustomerID FROM Customers)


A query acima pode ser convertida para:


SELECT  * FROM Orders O , Customers C
WHERE O.CustomerID = C.CustomerID


Ou ainda


SELECT * FROM Orders O INNER JOIN Customers C
ON O.CustomerID = C.CustomerID


As três query´s acima são equivalentes, sendo preferível a última.


Outros exemplos: as duas query’s abaixo


SELECT * FROM Customers
WHERE  CustomerID NOT IN (SELECT CustomerID FROM Orders)


SELECT *  FROM Customers C
WHERE  NOT EXISTS (SELECT CustomerID FROM Orders O WHERE C.CustomerID=O.CustomerID)


São equivalentes à seguinte query:


SELECT C.*
FROM Customers C LEFT OUTER JOIN Orders O
ON C.CustomerID = O.CustomerID
WHERE O.CustomerID IS NULL


Lembrem-se, sempre que possível é preferível que utilizemos um JOIN ao invés de uma subquery, pois o Query Otimizer (o mecanismo que otimiza as instruções enviada para o banco) pode executar algumas operações a mais quando se utiliza subquery’s, degradando assim a performance da execução.


7. Do mesmo modo que nas views, somente podemos colocar a cláusula ORDER BY em uma subquery se utilizarmos a cláusula TOP na subquery.



 

Avaliação:
Compartilhe:
  • Anterior Utilizando o RAISERROR21 anos atrás
  • Próximo SQL Server 2000 SP4 Beta21 anos atrás

Deixe uma resposta Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

MVP Reconnect Award

Categorias

  • Artigos (359)
  • Dica da Semana (95)
  • Documentação (54)
  • Downloads (113)
  • MSDE 2000 (3)
  • Sem categoria (1)
  • Tutoriais (9)

Posts recentes

  • #FechouBrasil #PartiuPortugal
  • Brigando com o erro “The cached MSI file is missing”
  • MCDBABRASIL está de volta
  • Documentando o Servidor SQL Server
  • Brigando com os Erros 17182, 17826 e 17120

SQL Server AlwaysOn Video Series

Video1: Introdução ao SQLServer2012 AlwaysOn


Video2: Introdução ao SQLServer2012 AlwaysOn Availability Group


Video3: Introdução ao SQLServer2012 AlwaysOn AVG-Demo


Video4: Introdução ao SQLServer2012 AlwaysOn Listener


Video5: Introdução ao SQLServer2012 AlwaysOn Readable Secondaries


Video6: Introdução ao SQLServer2012 AlwaysOn Readable Secondaries-Demo


Video7: Introdução ao SQLServer2012 AlwaysOn Failover Clustering


Serie SQL Server Failover Clustering End-to-End

Parte 1: Configuração da Rede e Ambiente


Parte 2: Configurando o Windows 2008 R2 Domain Controler e DNS


Parte 3: Preparando os nós para o Failover Cluster


Parte 4: Configurando um Failover Cluster de 2 nós


Parte 5: Configurando as LUNs no iSCSI Software Target (Parte 1)


Parte 6: Configurando as LUNs no iSCSI Software Target (Parte 2)


Parte 7: Apresentando as LUNs para os nós do Failover Cluster


Parte 8: Configurando os discos no Failover Cluster


Parte 9: Instalando a primeira instância virtual do SQL Server 2008


Parte 10: Instalando a segunda instância virtual do SQL Server 2008


Parte 11: Instalando e Configurando o MSDTC no Failover Cluster


Parte 12: Configurando Mount Points no Cluster e SQL Server 2008


Vídeo Extra: Removendo uma Instância do SQL Server 2008 R2 em Cluster


Alta Disponibilidade no SQL Server 2008 R2: Failover Clustering Overview


Alta Disponibilidade no SQL Server 2008 R2: Failover Clustering na Prática

Menu

  • Home
  • Sobre
  • Contato

Mais

  • RSS Feeds
2026 MCDBA Brasil.