SQL HAVING用法详解
2015-12-21 21:33
302 查看
来自:http://blog.csdn.net/wozeze1/article/details/6031318
HAVING 子句对 GROUP BY 子句设置条件的方式与 WHERE 和 SELECT 的交互方式类似。WHERE 搜索条件在进行分组操作之前应用;而 HAVING 搜索条件在进行分组操作之后应用。HAVING 语法与 WHERE 语法类似,但 HAVING 可以包含聚合函数。HAVING 子句可以引用选择列表中显示的任意项。
下面的示例按产品 ID 对 SalesOrderDetail 进行了分组,并且只包含那些订单合计大于 $1,000,000 且其平均订单数量小于 3 的产品组。
USE AdventureWorks;
GO
SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $1000000.00
AND AVG(OrderQty) < 3 ;
GO
请注意,如果 HAVING 中包含多个条件,那么这些条件将通过 AND、OR 或 NOT 组合在一起。
若要查看总销量大于 $2,000,000 的产品,请使用下面的查询:
USE AdventureWorks;
GO
SELECT ProductID, Total = SUM(LineTotal)
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $2000000.00 ;
GO
下面是结果集:
ProductID Total
----------- ----------------------
781 3864606.54937208
969 2010943.97244001
793 2897478.01200001
784 3699803.72383008
780 3880441.60780208
976 2079038.42948
795 2268057.09000002
783 4548164.01783709
779 4170215.3849281
782 5032968.13026809
794 2679200.01336002
753 2006264.4236
(12 row(s) affected)
若要确保对每种产品的计算中至少包含 1500 项,请使用 HAVING COUNT(*) > 1500 消除返回的销售总数小于 1500 项的产品。该查询类似于下面的示例:
USE AdventureWorks;
GO
SELECT ProductID, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(*) > 1500 ;
GO
理解应用 WHERE、GROUP BY 和 HAVING 子句的正确顺序对编写高效的查询代码会有所帮助:
WHERE 子句用来筛选 FROM 子句中指定的操作所产生的行。
GROUP BY 子句用来分组 WHERE 子句的输出。
HAVING 子句用来从分组的结果中筛选行。
对于可以在分组操作之前或之后应用的任何搜索条件,在 WHERE 子句中指定它们会更有效。这样可以减少必须分组的行数。应当在 HAVING 子句中指定的搜索条件只是那些必须在执行分组操作之后应用的搜索条件。
Microsoft SQL Server 2005 查询优化器可以处理这些条件中的大多数条件。如果查询优化器确定 HAVING 搜索条件可以在分组操作之前应用,那么它就会在分组之前应用。查询优化器可能无法识别所有可以在分组操作之前应用的 HAVING 搜索条件。建议将所有这些搜索条件放在 WHERE 子句中,而不是 HAVING 子句中。
下面的示例显示了带有聚合函数的 HAVING 子句。它按产品 ID 分组 SalesOrderDetail 表中的行,并消除其平均订单数量小于/等于 5 的产品。
USE AdventureWorks;
GO
SELECT ProductID
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID ;
GO
下面的示例显示了不带聚合函数的 HAVING 子句。它按名称分组 ProductModel 表中的行,并消除那些不以 Mountain 开头的名称。
USE AdventureWorks;
GO
SELECT pm.Name, AVG(ListPrice) AS 'Average List Price'
FROM Production.Product AS p
JOIN Production.ProductModel AS pm
ON p.ProductModelID = pm.ProductModelID
GROUP BY pm.Name
HAVING pm.Name LIKE 'Mountain%'
ORDER BY pm.Name ;
GO
请注意,ORDER BY 子句可用于排序 GROUP BY 子句的输出。
HAVING 子句对 GROUP BY 子句设置条件的方式与 WHERE 和 SELECT 的交互方式类似。WHERE 搜索条件在进行分组操作之前应用;而 HAVING 搜索条件在进行分组操作之后应用。HAVING 语法与 WHERE 语法类似,但 HAVING 可以包含聚合函数。HAVING 子句可以引用选择列表中显示的任意项。
下面的示例按产品 ID 对 SalesOrderDetail 进行了分组,并且只包含那些订单合计大于 $1,000,000 且其平均订单数量小于 3 的产品组。
USE AdventureWorks;
GO
SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $1000000.00
AND AVG(OrderQty) < 3 ;
GO
请注意,如果 HAVING 中包含多个条件,那么这些条件将通过 AND、OR 或 NOT 组合在一起。
若要查看总销量大于 $2,000,000 的产品,请使用下面的查询:
USE AdventureWorks;
GO
SELECT ProductID, Total = SUM(LineTotal)
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $2000000.00 ;
GO
下面是结果集:
ProductID Total
----------- ----------------------
781 3864606.54937208
969 2010943.97244001
793 2897478.01200001
784 3699803.72383008
780 3880441.60780208
976 2079038.42948
795 2268057.09000002
783 4548164.01783709
779 4170215.3849281
782 5032968.13026809
794 2679200.01336002
753 2006264.4236
(12 row(s) affected)
若要确保对每种产品的计算中至少包含 1500 项,请使用 HAVING COUNT(*) > 1500 消除返回的销售总数小于 1500 项的产品。该查询类似于下面的示例:
USE AdventureWorks;
GO
SELECT ProductID, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(*) > 1500 ;
GO
理解应用 WHERE、GROUP BY 和 HAVING 子句的正确顺序对编写高效的查询代码会有所帮助:
WHERE 子句用来筛选 FROM 子句中指定的操作所产生的行。
GROUP BY 子句用来分组 WHERE 子句的输出。
HAVING 子句用来从分组的结果中筛选行。
对于可以在分组操作之前或之后应用的任何搜索条件,在 WHERE 子句中指定它们会更有效。这样可以减少必须分组的行数。应当在 HAVING 子句中指定的搜索条件只是那些必须在执行分组操作之后应用的搜索条件。
Microsoft SQL Server 2005 查询优化器可以处理这些条件中的大多数条件。如果查询优化器确定 HAVING 搜索条件可以在分组操作之前应用,那么它就会在分组之前应用。查询优化器可能无法识别所有可以在分组操作之前应用的 HAVING 搜索条件。建议将所有这些搜索条件放在 WHERE 子句中,而不是 HAVING 子句中。
下面的示例显示了带有聚合函数的 HAVING 子句。它按产品 ID 分组 SalesOrderDetail 表中的行,并消除其平均订单数量小于/等于 5 的产品。
USE AdventureWorks;
GO
SELECT ProductID
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID ;
GO
下面的示例显示了不带聚合函数的 HAVING 子句。它按名称分组 ProductModel 表中的行,并消除那些不以 Mountain 开头的名称。
USE AdventureWorks;
GO
SELECT pm.Name, AVG(ListPrice) AS 'Average List Price'
FROM Production.Product AS p
JOIN Production.ProductModel AS pm
ON p.ProductModelID = pm.ProductModelID
GROUP BY pm.Name
HAVING pm.Name LIKE 'Mountain%'
ORDER BY pm.Name ;
GO
请注意,ORDER BY 子句可用于排序 GROUP BY 子句的输出。
相关文章推荐
- redis 命令总结
- mysql 中查询语句表达式REGEXP用法
- mongodb复杂查询
- sqlite的基础
- RMAN实战10:完全恢复数据库
- redis服务启动关闭以及其他命令实践
- C#中使用SQL存储过程说明
- 【mysql】关于硬件方面的一些优化
- oracle Caused by: java.sql.BatchUpdateException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
- MySQL 5.6 for Windows 解压缩版配置安装
- PHP安装redis扩展
- ITOO项目之Memcached
- MySQL复制 -- Binlog (1)
- oracle中的rownum
- SSDB:高性能数据库服务器
- oracle用户名以及口令忘记了咋办?
- SQL SERVER2005的主动通告事件
- MYSQL主从同步
- 12 可插入数据库
- c#调用SqlServer中的存储过程