Filtrando linhas utilizando WHERE e HAVING

As cláusulas WHERE e HAVING em uma instrução SELECT controlam as linhas de tabelas de origem utilizadas para compilar o conjunto de resultados. WHERE e HAVING são filtros. Eles especificam uma série de critérios de pesquisa e somente as linhas que atendem aos termos dos critérios de pesquisa são utilizadas para compilar o conjunto de resultados. As linhas que atendem aos critérios de pesquisa são qualificadas para participar do conjunto de resultados. Por exemplo, a cláusula WHERE na instrução SELECT a seguir qualifica as linhas apenas para um território de vendas específico.

USE AdventureWorks2008R2;
GO
SELECT c.CustomerID, s.Name
FROM AdventureWorks2008R2.Sales.Customer c
JOIN AdventureWorks2008R2.Sales.Store s
ON s.BusinessEntityID = c.CustomerID
WHERE c.TerritoryID = 1;

A cláusula HAVING geralmente é utilizada com a cláusula GROUP BY para filtrar os resultados dos valores agregados. Entretanto, HAVING pode ser especificada sem GROUP BY. A cláusula HAVING especifica filtros adicionais aplicados após a cláusula WHERE ser filtrada. Esses filtros podem ser aplicados a uma função de agregação utilizada na lista de seleção. No exemplo a seguir, a cláusula WHERE qualifica apenas pedidos que vendem um produto com um preço unitário superior a $100 e a cláusula HAVING restringe o resultado apenas a pedidos que possuem mais de 100 unidades.

USE AdventureWorks2008R2;
GO
SELECT OrdD1.SalesOrderID AS OrderID,
       SUM(OrdD1.OrderQty) AS "Units Sold",
       SUM(OrdD1.UnitPrice * OrdD1.OrderQty) AS Revenue
FROM Sales.SalesOrderDetail AS OrdD1
WHERE OrdD1.SalesOrderID in (SELECT OrdD2.SalesOrderID
    FROM Sales.SalesOrderDetail AS OrdD2
    WHERE OrdD2.UnitPrice > $100)
GROUP BY OrdD1.SalesOrderID
HAVING SUM(OrdD1.OrderQty) > 100;

Critérios de pesquisa nas cláusulas WHERE e HAVING

Os critérios de pesquisa, ou qualificações, nas cláusulas WHERE e HAVING podem incluir:

  • Operadores de comparação, como: =, < >, < e >

    Por exemplo, a consulta a seguir recupera as linhas da tabela Product para os produtos que estão na classe H.

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE Class = 'H'
    ORDER BY ProductID;
    
  • Intervalos (BETWEEN e NOT BETWEEN)

    Por exemplo, a consulta a seguir recupera as linhas da tabela Product com preços de lista de R$ 100,00 até R$ 500,00.

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE ListPrice BETWEEN 100 and 500
    ORDER BY ListPrice;
    
  • Listas (IN, NOT IN)

    Por exemplo, a consulta a seguir recupera produtos que estão dentro de uma lista de cores.

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE Color IN ('Multi', 'Silver')
    ORDER BY ProductID;
    
  • Correspondências padrão (LIKE e NOT LIKE)

    Por exemplo, a consulta a seguir recupera as linhas da tabela Product cujo nome de produto começa com as letras Ch.

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE Name LIKE 'Ch%'
    ORDER BY ProductID;
    
    ObservaçãoObservação

    As únicas condições WHERE que podem ser utilizadas nas colunas text são funções que retornam outros tipos de dados, como PATINDEX (); ou os operadores, como IS NULL, IS NOT NULL, LIKE e NOT LIKE.

  • Valores nulos (IS NULL e IS NOT NULL)

    Por exemplo, a consulta a seguir recupera as linhas da tabela Customer cujos IDs do vendedor dos clientes não são NULL.

    SELECT s.Name
    FROM AdventureWorks2008R2.Sales.Customer c
    JOIN AdventureWorks2008R2.Sales.Store s
    ON c.CustomerID = S.CustomerID
    WHERE c.CustomerID IS NOT NULL
    ORDER BY s.Name;
    
    ObservaçãoObservação

    Tome cuidado ao comparar valores nulos. Por exemplo, especificar = NULL não é a mesma coisa que especificar IS NULL. Para obter mais informações, consulte Valores nulos.

  • Todos os registros (=ALL, >ALL, <= ALL, ANY)

    Por exemplo, a consulta a seguir recupera a ordem e a ID do produto da tabela SalesOrderDetail em que a quantidade do produto enviada é maior que a quantidade enviada de qualquer outro produto na classe H.

    USE AdventureWorks2008R2;
    GO
    SELECT OrdD1.SalesOrderID, OrdD1.ProductID
    FROM Sales.SalesOrderDetail OrdD1
    WHERE OrdD1.OrderQty > ALL
          (SELECT OrdD2.OrderQty
           FROM Sales.SalesOrderDetail OrdD2 JOIN Production.Product Prd
                 ON OrdD2.ProductID = Prd.ProductID
           WHERE Prd.Class = 'H');
    GO
    
  • Combinações dessas condições (AND, OR, NOT)

    Por exemplo, a consulta a seguir recupera todos os produtos para os quais o preço da lista é inferior a R$ 500,00 ou a classe do produto é L e a linha do produto é S.

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE ListPrice < 500
       OR (Class = 'L' AND ProductLine = 'S');
    

    Observe que quando você pesquisa uma cadeia de caracteres Unicode em uma cláusula WHERE, o caractere N é colocado antes da cadeia de caracteres de pesquisa:

    SELECT BusinessEntityID 
    FROM AdventureWorks2008R2.Sales.Store 
    WHERE Name = N'Riders Company';