在Joins中使用Aggregate函数时如何使用Group By子句?

时间:2011-06-21 10:51:40

标签: sql sql-server sql-server-2005 group-by aggregate-functions

我想加入三个表并计算表A的总和(数量)。 我试了一下,得到了想要的输出。但是我仍然混淆基于聚合函数和Group By子句。

在通过连接两个或多个表计算总和值时,我们需要在Group By子句中提及哪些列,为什么我们需要提供这些列?

例如:这是我的表格和所需的查询。

TableA: ItemID, JobOrderID, CustomerID, DivisionID, Quantity
TableB: ItemID, ItemName, SpecificationID
TableC: SpecificationID, SpecificationName
TableD: DivisionID, DivisionName
TableE: JobOrderID, JobOrderNo.
TableF: CustomerID, CustomerName

我希望根据ItemIDCustomerIDJobOrderIDDivisionID获得总和(数量)。

我编写了以下查询,它运行正常。但是,如果我删除Group By子句中的任何列,则它不会提供所需的结果。为什么? Group By子句在这里做什么?如何在使用Aggregate函数时指定Group By子句?这是我的查询。

    SELECT 
            B.ItemName + ' - ' + C.SpecificationName AS 'ItemName',
            SUM(A.Quantity) AS 'Quantity',
            A.ItemID,
            D.DivisionName,
            F.CustomerName,
            E.JobOrderNo,
            A.DivisionID,
            A.JobOrderID,
            A.CustomerID

    FROM
            TableA A  
            INNER JOIN TableB B ON B.ItemID = A.ItemID 
            INNER JOIN TableC C ON C.SpecificationID = B.SpecificationID
            INNER JOIN TableD D ON D.DivisionID = A.DivisionID
            LEFT JOIN TableE E ON E.JobOrderID = A.JobOrderID
            LEFT JOIN TableF F ON F.CustomerID = A.CustomerID
    WHERE
            A.ItemID = @ItemID
    GROUP BY
            A.ItemID,
            A.JobOrderID,
            A.DivisionID,
            A.CustomerID,
            D.DivisionName,
            F.CustomerName,
            E.JobOrderNo,
            B.ItemName,
            C.SpecificationName

任何人都应以此为例来对Group By Clause提出建议。

3 个答案:

答案 0 :(得分:6)

GROUP BY对于指定列的任何唯一组合都会进行聚合(如sum,min等)。如果你没有在GROUP BY子句或者聚合函数中指定一些列名,那么SQL引擎就不知道它应该为那种列返回哪个值。

答案 1 :(得分:5)

GROUP BY (Transact-SQL)通过SQL Server 2008 R2中的一个或多个列或表达式的值将选定的行集合分组到一组摘要行中。每组返回一行。 SELECT子句列表中的聚合函数提供有关每个组而不是单个行的信息。

SELECT a.City, COUNT(bea.AddressID) AS EmployeeCount
FROM Person.BusinessEntityAddress AS bea 
    INNER JOIN Person.Address AS a
        ON bea.AddressID = a.AddressID
GROUP BY a.City
  

GROUP BY子句有一个   符合ISO标准的语法和   不符合ISO标准的语法。只有一个   语法样式可以在单个中使用   SELECT语句。使用ISO   所有新作品的兼容语法。该   提供了不符合ISO的语法   为了向后兼容。

ISO兼容语法中, 列表中任何非聚合表达式中的每个表或视图列都必须包含在GROUP BY列表中。

select pub_id, type, avg(price), sum(total_sales)
from titles
group by pub_id, type

参考Organizing query results into groups: the group by clause

  

Sybase 不符合ISO标准的语法解除对您的限制   在select列表中包含或省略   查询包含group by

     
      
  • 选择列表中的列不限于分组列   和向量一起使用的列   聚集体。

  •   
  • group by指定的列不限于非聚合列   选择列表中的列。

  •   

示例:

select type, title_id, avg(price), avg(advance) 
from titles 
group by type 

答案 2 :(得分:2)

要使用sum而不使用group by这样的聚合函数,请使用over子句。

请参阅: http://msdn.microsoft.com/en-us/library/ms189461.aspx

示例:

CREATE TABLE #a (ida int, name varchar(50))
CREATE TABLE #b  (ida int, number int)

INSERT INTO #a VALUES(1,'one')
INSERT INTO #a VALUES(2,'two')

INSERT INTO #b VALUES(1,2)
INSERT INTO #b VALUES(1,3)
INSERT INTO #b VALUES(2,1)

SELECT DISTINCT a.ida, sum(number) OVER (PARTITION BY a.ida) FROM #a a
INNER JOIN #b b on a.ida = b.ida