SQL Server:长查询中的聚合函数和GROUP BY

Too*_*ool 3 sql sql-server ssms group-by aggregate-functions

我前几天在SQL Server中编写了一个查询,并且必须得到一个添加到查询中的列的总和.

现在,我必须添加sum列的查询已经有大约20个选定的列.

为了使总和(聚合函数)起作用,我必须GROUP BY为每个预选列添加.

这最终成为一项非常乏味和无聊的任务(请参阅下面的查询).我不得不在查询中添加大约50个新行,只是为了让一列工作的SUM.

有没有办法使用SQL Server Management Studio自动编写此类查询?

这与其他数据库(例如PL/SQL,Oracle,MySQL?)相同吗?

这就是查询的样子.

SELECT 
       mvLogisticContracts.[mvLogisticContract_id]
      ,mvLogisticContracts.[CONTRACTNUMBER] 
      ,mvLogisticContracts.[CUSTNMBR]
      ,mvLogisticContracts.[DateCreated]
      ,mvLogisticContracts.[TruckAllocatedTotal]      ,mvLogisticContracts.[mvLOgisticAddress_id_StartOriginal]
          ,mvLogisticContracts.[mvLogisticAddress_id_StartOriginal]       ,mvLogisticContractLineItems.[LineItemQuantity]     ,mvLogisticContractLineItems.[LineItemNo]
          ,mvLogisticContractLineItems.[OffloadRequired]
          ,mvLogisticContractLineItems.[CarrierRequested]     ,mvLogisticContractLineItems.[RequestedSerialNo]
          ,mvLogisticContractLineItems.[mvLogisticAddress_id_Start]
          ,mvLogisticContractLineItems.[DateReadyBy]      ,mvLogisticContractLineItems.[DateCustomerRequested],
          mvLogisticContractLineItems.[mvLogisticContractLineItem_id]
      ,mvLogisticSalespersons.[FirstName],mvLogisticSalespersons.[LastName],
      mvLogisticServiceTypes.ServiceType,
      mvLogisticStatuses.Description,
      mvLogisticSKUs.[SKU],       mvLogisticSKUs.[Length],
      a1.CITY as \"CityStart\", a1.AddressName as \"AddressNameStart\", a1.Address1 as \"Address1Start\", a1.STATE as \"StateStart\", a1.ZIP as \"ZipStart\",
      a2.CITY as \"CityEnd\", a2.AddressName as \"AddressNameEnd\", a2.Address1 as \"Address1End\", a2.STATE as \"StateEnd\", a2.ZIP as \"ZipEnd\",
      mvLogisticContracts.[mvLogisticAddress_id_Start] AS aa1,
      mvLogisticContracts.[mvLogisticAddress_id_End] AS aa2,
      SUM(mvLogisticReleases.ReleaseQuantity) as ReleaseQtySum
            FROM mvLogisticContractLineItems
            LEFT JOIN mvLogisticContracts ON mvLogisticContractLineItems.mvLogisticContract_id = mvLogisticContracts.mvLogisticContract_id
            LEFT JOIN mvLogisticSalespersons ON mvLogisticContracts.[mvLogisticSalesperson_id] = mvLogisticSalespersons.[mvLogisticSalesperson_id]
            LEFT JOIN mvLogisticServiceTypes ON mvLogisticContractLineItems.mvLogisticServiceType_id = mvLogisticServiceTypes.mvLogisticServiceType_id
            LEFT JOIN mvLogisticStatuses ON mvLogisticContractLineItems.mvLogisticStatus_id = mvLogisticStatuses.mvLogisticStatus_id
            LEFT JOIN mvLogisticSKUs ON mvLogisticContractLineItems.[SKU_id] = mvLogisticSKUs.[SKU_id]
            LEFT JOIN mvLogisticAddresses a1 ON a1.[mvLogisticAddress_id] = mvLogisticContractLineItems.[mvLogisticAddress_id_Start]
            LEFT JOIN mvLogisticAddresses a2 ON a2.[mvLogisticAddress_id] = mvLogisticContractLineItems.[mvLogisticAddress_id_End]
            /*LEFT JOIN mvLogisticAddresses a1 ON a1.[mvLogisticAddress_id] = mvLogisticContracts.[mvLogisticAddress_id_Start]
            LEFT JOIN mvLogisticAddresses a2 ON a2.[mvLogisticAddress_id] = mvLogisticContracts.[mvLogisticAddress_id_End]*/
            LEFT JOIN mvLogisticReleases ON mvLogisticContractLineItems.mvLogisticContractLineItem_id = mvLogisticReleases.mvLogisticContractLineItem_id
            GROUP BY
            mvLogisticContracts.[mvLogisticContract_id]
      ,mvLogisticContracts.[CONTRACTNUMBER] 
      ,mvLogisticContracts.[CUSTNMBR]
      ,mvLogisticContracts.[DateCreated]
      ,mvLogisticContracts.[TruckAllocatedTotal]      ,mvLogisticContracts.[mvLOgisticAddress_id_StartOriginal]
          ,mvLogisticContracts.[mvLogisticAddress_id_StartOriginal]       ,mvLogisticContractLineItems.[LineItemQuantity]     ,mvLogisticContractLineItems.[LineItemNo]
          ,mvLogisticContractLineItems.[OffloadRequired]
          ,mvLogisticContractLineItems.[CarrierRequested]     ,mvLogisticContractLineItems.[RequestedSerialNo]
          ,mvLogisticContractLineItems.[mvLogisticAddress_id_Start]
          ,mvLogisticContractLineItems.[DateReadyBy]      ,mvLogisticContractLineItems.[DateCustomerRequested],
          mvLogisticContractLineItems.[mvLogisticContractLineItem_id]
      ,mvLogisticSalespersons.[FirstName],mvLogisticSalespersons.[LastName],
      mvLogisticServiceTypes.ServiceType,
      mvLogisticStatuses.Description, 
      mvLogisticSKUs.[SKU],       
      mvLogisticSKUs.[Length], 
      a1.CITY, a1.AddressName, a1.Address1, a1.STATE, a1.ZIP, 
      a2.CITY, a2.AddressName, a2.Address1, a2.STATE, a2.ZIP, 
      mvLogisticContracts.[mvLogisticAddress_id_Start], 
      mvLogisticContracts.[mvLogisticAddress_id_End]
Run Code Online (Sandbox Code Playgroud)

Fre*_*tka 8

子查询和公用表表达式(CTE)是将聚合隔离到易于连接到主SELECT语句的本地化点的两种方法.

相关/同步子查询示例:

SELECT c.contract_id, c.contractnum, c.customernum,
    ( SELECT SUM( li.price * li.orderquantity ) 
     FROM lineitems li 
     WHERE li.contract_id = c.contract_id
     ) AS grand_total
FROM contracts c 
WHERE ...
Run Code Online (Sandbox Code Playgroud)

在SELECT列表中引用相关子查询是返回单个值的便捷方法.

加入CTE:

WITH ordersummary AS 
( SELECT li.contract_id, 
      COUNT( DISTINCT li.partnum ) AS distinctproducts, 
      SUM( li.orderquantity ) AS itemcount,
      SUM( li.price * li.orderquantity) AS totalprice,
      MIN( p.ship_ready_date ) AS earliest_partial_ship_date,
      MAX( p.ship_ready_date ) AS earliest_complete_ship_date
      FROM lineitems li 
      INNER JOIN parts p 
          ON p.partnum = li.partnum
      GROUP BY li.contract_id
)
SELECT c.contract_id, c.contractnum, c.customernum,
s.distinctproducts, s.itemcount, s.totalprice,
s.earliest_partial_ship_date, s.earliest_complete_ship_date
FROM contracts c 
INNER JOIN ordersummary s
ON s.contract_id = c.contract_id
WHERE ...
Run Code Online (Sandbox Code Playgroud)

加入表达式:

SELECT c.contract_id, c.contractnum, c.customernum,
s.distinctproducts, s.itemcount, s.totalprice,
s.earliest_partial_ship_date, s.earliest_complete_ship_date
FROM contracts c 
INNER JOIN
( SELECT li.contract_id, 
      COUNT( DISTINCT li.partnum ) AS distinctproducts, 
      SUM( li.orderquantity ) AS itemcount,
      SUM( li.price * li.orderquantity) AS totalprice,
      MIN( p.ship_ready_date ) AS earliest_partial_ship_date,
      MAX( p.ship_ready_date ) AS earliest_complete_ship_date
      FROM lineitems li 
      INNER JOIN parts p 
          ON p.partnum = li.partnum
      GROUP BY li.contract_id
) AS s
ON s.contract_id = c.contract_id
WHERE ...
Run Code Online (Sandbox Code Playgroud)