前几天我在 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]
最佳答案
子查询和公用表表达式 (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 ...
在您的 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 ...
加入表达式:
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 ...
关于SQL 服务器 : aggregate functions and GROUP BY in long queries,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12486079/