【问题标题】:How to Use Group By clause when we use Aggregate function in the Joins?在 Joins 中使用 Aggregate 函数时如何使用 Group By 子句?
【发布时间】:2011-06-21 10:51:40
【问题描述】:

我想连接三个表并计算表 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 子句在这里做什么?使用聚合函数时如何指定 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 提出建议。

【问题讨论】:

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


    【解决方案1】:

    GROUP BY 对指定列的任何唯一组合进行聚合(如 sum、min 等)。如果您没有在 GROUP BY 子句或聚合函数中指定某些列名,SQL 引擎将不知道它应该为该类型的列返回哪个值。

    【讨论】:

    • 因此,如果我们选择某些列意味着,我们也需要在 Group By 子句中给出这些列。是这样吗?
    • 是的,选定的列必须在group by 中或类似:select max(column_name)
    【解决方案2】:

    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 的语法。只有一个 语法风格可以单独使用 选择语句。使用 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

    Sybasenon-ISO-compliant 语法解除了对你能做什么的限制 在select 列表中包含或省略 包含group by 的查询:

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

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

    例子:

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

    【讨论】:

    • 因此,如果我们选择某些列意味着,我们也需要在 Group By 子句中给出这些列。是这样吗?
    • 这更有意义,group by 只显示组的代表行,因此所有非聚合字段都应包含在 group by 子句中。
    【解决方案3】:

    要使用 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
    

    【讨论】:

      猜你喜欢
      • 2021-03-26
      • 2011-09-21
      • 2015-03-28
      • 1970-01-01
      • 2011-09-25
      • 2014-08-14
      • 1970-01-01
      • 2019-10-03
      • 1970-01-01
      相关资源
      最近更新 更多