怎么在SQLServer计算列和平均值

  严格来说,Having并不需要一个子表,但没有子表的Having并没有实际意义。如果你只需要一个表,那么你可以用Where子句达到一切目的。为进行实践,Having预先假定至少两个表和一个基于第二个表的合计函数。

  下面是一个简单的例子:你想要订单总数超过25000美元的客户清单。你需要适当连接的三个表:Customer、SalesOrderHeader和SalesOrderDetail。然后,你求Detail的和,并将总数与25000美元进行比较。查看列表A。

  查看列表A中的代码时,有一件事情并不明显,即LineTotal列被计算。你可以像求实际的列的和一样求出已计算列的和。但是,你不能在同一个操作中执行两个不同层次的合计函数。

  SELECT

  Sales.Customer.CustomerID,

  Sales.SalesOrderHeader.SalesOrderID,

  SUM(Sales.SalesOrderDetail.LineTotal)

  AS SubTotalFROM

  Sales.Customer

  INNER JOIN Sales.SalesOrderHeader

  ON Sales.SalesOrderHeader.Customer

  ID = Sales.Customer.CustomerID

  INNER JOIN Sales.SalesOrderDetail

  ON Sales.SalesOrderDetail.SalesOrder

  ID = Sales.SalesOrderHeader.SalesOrderIDGROUP BY

  Sales.Customer.CustomerID,

  Sales.SalesOrderHeader.SalesOrder

  IDHAVING SUM(LineTotal) > 25000.00ORDER BY

  Sales.Customer.CustomerID,

  SalesOrderID ;列表A:

  假设你希望知道所有客户的平均销售额。你可以使用列表B中的代码,它返回如下错误信息:

  SELECT

  Sales.SalesOrderHeader.SalesOrderID,

  AVG(SUM(Sales.SalesOrderDetail.LineTotal))

  AS AverageFROM

  Sales.SalesOrderHeader

  INNER JOIN Sales.SalesOrderDetail

  ON Sales.SalesOrderDetail.SalesOrder

  ID = Sales.SalesOrderHeader.SalesOrder

  IDGROUP BY

  Sales.SalesOrderHeader.SalesOrderID列表B:

  Msg 130, Level 15, State 1, Line 1

  Cannot perform an aggregate function on an expression

  containing an aggregate or a subquery.错误信息:

  你可以将平均值的计算过程进行分解来解决这个问题。你可以将第一部分(SUM)编写成一个表值UDF,如列表C所示。你可以根据列表D中的函数计算平均值。列表E说明你如何能够进行组合。

  USE [AdventureWorks]

  GO

  /****** Object: UserDefinedFunction

  [dbo].[SalesTotals_fnt]

  Script Date: 12/09/2006 11:32:54 ******/

  SET ANSI_NULLS ON

  GO

  SET QUOTED_IDENTIFIER ON

  GO

  CREATE FUNCTION [dbo].[SalesTotals_fnt]()

  RETURNS TABLE

  AS RETURN

  (SELECT SalesOrderID,

  SUM(LineTotal)AS TotalSale

  FROM Sales.SalesOrderDetail

  GROUP BY Sales.SalesOrderDetail.SalesOrderID)列表C:

  CREATE FUNCTION [dbo].[AverageSale_fns] (

  -- Add the parameters for the function here

  -- )RETURNS money

  ASBEGIN

  -- Declare the return variable here

  DECLARE @Result money

  -- Add the T-SQL statements to compute the return value here

  SET @Result =(SELECTAvg(TotalSale)AS AverageSale

  FROM dbo.SalesTotals_fnt())

  -- Return the result of the function

  RETURN @Result

  END列表D:

  DECLARE @Avg moneySELECT @Avg = dbo.AverageSale_fns()

  SELECT *, @Avg as Average,

  TotalSale / @Avg as Ratio, CASE

  WHEN TotalSale / @Avg > 1 THEN 'Above Average'

  WHEN TotalSale / @Avg < 1 THEN 'Below Average'

  ELSE 'Average' END

  FROM dbo.SalesTotals_fnt()列表E:

  现在你知道了如何根据一个子表使用Having子句来测试合计值。当你需要在一个查询中使用两个不同的合计函数时,最好是把它们分解成单独的函数,然后再进行组合(如前一个例子所说明的)。

时间: 2024-12-31 21:20:50

怎么在SQLServer计算列和平均值的相关文章

如何在SQL Server计算列和平均值

严格来说,Having并不需要一个子表,但没有子表的Having并没有实际意义.如果你只需要一个表,那么你可以用Where子句达到一切目的.为进行实践,Having预先假定至少两个表和一个基于第二个表的合计函数. 下面是一个简单的例子:你想要订单总数超过25000美元的客户清单.你需要适当连接的三个表:Customer.SalesOrderHeader和SalesOrderDetail.然后,你求Detail的和,并将总数与25000美元进行比较.查看列表A. 查看列表A中的代码时,有一件事情并

在SQL Server数据库中求计算列和平均值

 严格来说,Having并不需要一个子表,但没有子表的Having并没有实际意义.如果你只需要一个表,那么你可以用Where子句达到一切目的.为进行实践,Having预先假定至少两个表和一个基于第二个表的合计函数. 下面是一个简单的例子:你想要订单总数超过25000美元的客户清单.你需要适当连接的三个表:Customer.SalesOrderHeader和SalesOrderDetail.然后,你求Detail的和,并将总数与25000美元进行比较.查看列表A. 查看列表A中的代码时,有一件事情

用SQL Server HAVING子句计算列和平均值

在本文中,简单说明这个子句,并提供一些代码实例,这是说明HAVING子句用法的最佳方法. 严格来说,HAVING并不需要一个子表,但没有子表的HAVING并没有实际意义.如果你只需要一个表,那么你可以用WHERE子句达到一切目的.为进行实践,HAVING预先假定至少两个表和一个基于第二个表的合计函数. 下面是一个简单的例子:你想要订单总数超过25000美元的客户清单.你需要适当连接的三个表:Customer.SalesOrderHeader和SalesOrderDetail.然后,你求Detai

第十章——维护索引(8)——在计算列中创建索引提高性能

原文:第十章--维护索引(8)--在计算列中创建索引提高性能 前言: 在理解计算列上的索引之前,先了解计算列的基本知识.计算列由可以使用同一表中的其他列的表达式计算得来.表达式可以是非计算列的列名.常量.函数,也可以是用一个或多个运算符连接的上述元素的任意组合.表达式不能为子查询. 默认情况下,计算列是一个虚拟的列,并且可以在调用时重新计算,直到在CREATE TABLE或者ALTER TABLE 命令中使用PERSISTED. 如果列定义成PERSISTED,会存放计算值,并存放在原始列上更新

数据库快照,自定义函数与计算列

数据库快照,自定义函数与计算列 1.数据库快照 数据库快照就是保存某个数据库在快照那一瞬间的状态.快照和备份原理上有所不同,但是功能有一点相同那就是可以将数据还原为备份的那个时刻.快照的原理是新建一个数据库指针,在原数据库没有变化的情况下快照是不占用空间的,而数据库发生了变化,那么在变化前,被修改的数据页会先复制一份到快照文件中,然后再对原数据页进行修改.显然这样做的好处就是比备份数据库占用空间小.快照是只读的,你可以直接在SQL语句中把他当数据库用: use snap1;--使用快照 sele

用两种不同的方法来求实现数字字符串的最大,最小和平均值

字符串 用两种不同的方法来求实现数字字符串的最大,最小和平均值 <%@ LANGUAGE = "VBScript"ENABLESESSIONSTATE = False %><%'1. Selecting the numbers from a string:myString = "2, 4, 6, 8, 10, 12"aValues = Split(myString, ",", -1, 1)</P><P>F

SQLServer“标识列”的相关问题

  下面我们看一张表:想一想在数据库SQLServer中我们如何能更简便的向这张表格中添加数据呢? 仔细观察此表我们不难发现,ID字段的这列数据的添充是有规律可循的,它是一个等比自增的数列,向数据表中添加这样的数据有没有简单的方法呢? 这就谈到了SQLServer标识列的问题.我查询一些资料做了总结,在此和大家一起分享受与交流. (1)标识列的定义 标识列,(通常也称为"标识字段"或者称为"自动增长字段")是一行记录区别其它记录的标识,为的也是能唯一地检索出该行记录

SQL Server利用HashKey计算列解决宽字段查询的性能问题

SQL Server利用HashKey计算列解决宽字段查询的性能问题 主人翁        本文主人翁:MSSQL菜鸟和MSSQL老鸟. 问题提出        某年某月某日,某MSSQL菜鸟满脸愁容的跑到老鸟跟前,心灰意懒的对老鸟说"我最近遇到一个问题,很大的问题,对,非常大的问题".老鸟不急不慢的推了推2000度超级近视眼镜框,慢吞吞的说:"说来听听".        "我有一个100万数据量的表,有一个宽度为7500字段,不幸的是现在我需要根据这个字

数据库一个简单的计算列问题

问题描述 数据库一个简单的计算列问题 定义学生表,其中规定: ? ? 学号列是主关键字: 院系列为计算列(取学号列的第 3 和第 4 个字符) ,并且院系值参照院系表的编号值(院 系表是被参照表,主关键字是编号:参照表是学生表,外部关键字是院系) ,此约束说明 一名学生一定属于某个院系: ? ? ? 姓名列不允许为空值: 性别必须取值"男"或"女": 学生的学籍状态为正常.留级.休学或退学. 代码: create table student.学生 (学号 char(