Filtrar filas mediante WHERE y HAVING

Las cláusulas WHERE y HAVING de una instrucción SELECT controlan qué filas de las tablas de origen se usan para generar el conjunto de resultados. WHERE y HAVING son filtros. Especifican una serie de condiciones de búsqueda y para crear el conjunto de resultados sólo se usan las filas que cumplan los términos de dichas condiciones. Se dice que las filas que cumplen las condiciones de búsqueda están calificadas para participar en el conjunto de resultados. Por ejemplo, la cláusula WHERE de esta instrucción SELECT sólo califica las filas para una zona de ventas específica:

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;

La cláusula HAVING se usa normalmente junto con la cláusula GROUP BY para filtrar los resultados de valores de agregado. Sin embargo, HAVING puede especificarse sin GROUP BY. La cláusula HAVING especifica filtros adicionales que se aplican después de que la cláusula WHERE aplica el filtro. Estos filtros se pueden aplicar a una función de agregado que se utilice en la lista SELECT. En el ejemplo siguiente, la cláusula WHERE sólo califica a los pedidos de un producto cuyo precio unitario supere los $100 y la cláusula HAVING restringe adicionalmente el resultado a aquellos pedidos que incluyan más 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;

Condiciones de búsqueda en las cláusulas WHERE y HAVING

Las condiciones de búsqueda o calificaciones de las cláusulas WHERE y HAVING pueden incluir lo siguiente:

  • Operadores de comparación, como: =, < >, < y >

    Por ejemplo, en la siguiente consulta se recuperan las filas de la tabla Product de los productos que se encuentren en la clase H.

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

    Por ejemplo, en la siguiente consulta se recuperan las filas de la tabla Product cuyos precios de lista se encuentren entre 100 y 500 dólares.

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

    Por ejemplo, la consulta siguiente recupera los productos que queden en una lista de colores.

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE Color IN ('Multi', 'Silver')
    ORDER BY ProductID;
    
  • Coincidencias de patrón (LIKE y NOT LIKE)

    Por ejemplo, en la siguiente consulta se recuperan las filas de la tabla Product en las que el nombre del producto empiece con las letras Ch:

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE Name LIKE 'Ch%'
    ORDER BY ProductID;
    

    Nota

    Las únicas condiciones WHERE que puede utilizar en las columnas text son las funciones que devuelven otro tipo de datos, como PATINDEX(), o los operadores, como IS NULL, IS NOT NULL, LIKE y NOT LIKE.

  • Valores NULL (IS NULL e IS NOT NULL)

    Por ejemplo, en la siguiente consulta se recuperan las filas de la tabla Customer en las que los identificadores de vendedores de los clientes no son 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;
    

    Nota

    Preste atención al comparar valores NULL. Por ejemplo, especificar = NULL no es lo mismo que especificar IS NULL. Para obtener más información, vea Valores NULL.

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

    Por ejemplo, en la siguiente consulta se recuperan los identificadores de pedidos y de productos de la tabla SalesOrderDetail en los que la cantidad del producto enviado sea mayor que la cantidad enviada de cualquier producto de la clase 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
    
  • Combinaciones de estas condiciones (AND, OR, NOT)

    Por ejemplo, en la siguiente consulta se recuperan todos los productos cuyo precio de lista sea inferior a 500 dólares o para los que la clase de producto sea L y la línea de productos sea S.

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

    Tenga en cuenta que cuando busque una cadena Unicode en una cláusula WHERE, debe colocar el carácter N antes de la cadena de búsqueda:

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