更新语句GROUP BY的SQL Server错误

时间:2015-10-21 15:24:46

标签: sql-server

UPDATE #IncrementalCreditHeaderResult
SET TotalDeliveredVolume = SUM(TSR.QuantityBilled) FROM dbo.ThruputServiceRendereds TSR WITH(NOLOCK)
INNER JOIN Services S ON S.ServiceId = TSR.ServiceID 
    AND  S.ServiceCode = 'TRAN' 
    AND TSR.TransactionCompleteDatetime BETWEEN @service_start_date AND @endDate
INNER JOIN Terminals T ON T.TerminalID = TSR.TerminalID 
    AND T.TerminalNumber = @terminal_number
INNER JOIN Contracts C ON C.ContractID = TSR.ContractID 
    AND C.ContractNumber = @contract_number
WHERE MonthPeriod = Format(@service_start_date, N'MMM-yy')
GROUP BY TotalDeliveredVolume

当我使用group by时,我收到此错误:

  

Msg 157,Level 15,State 1,Procedure rpt_Test,Line 106

     

聚合可能不会出现在UPDATE语句的集合列表中。

2 个答案:

答案 0 :(得分:2)

错误为您提供了提示。您无法在SUM语句的SET中使用UPDATE

一个简单的替代方法是创建一个#temp表并用聚合结果填充它,然后更新。

我在这里捅了一下 - 推断我能做什么。

CREATE TABLE #tmp(QuantityBilled INT, ServiceID INT, TerminalID INT, ContractID INT)
INSERT INTO #tmp(QuantityBilled, ServiceID, TerminalID, ContractID)
SELECT SUM(TSR.QuantityBilled), TSR.ServiceID , TSR.TerminalID, TSR.ContractID
FROM dbo.ThruputServiceRendereds TSR WITH(NOLOCK)
WHERE TSR.TransactionCompleteDatetime BETWEEN @service_start_date AND @endDate
GROUP BY TSR.ServiceID

UPDATE #IncrementalCreditHeaderResult
SET TotalDeliveredVolume = TSR.QuantityBilled
FROM #tmp TSR 
INNER JOIN Services S ON S.ServiceId = TSR.ServiceID 
    AND  S.ServiceCode = 'TRAN' 
INNER JOIN Terminals T ON T.TerminalID = TSR.TerminalID 
    AND T.TerminalNumber = @terminal_number
INNER JOIN Contracts C ON C.ContractID = TSR.ContractID 
    AND C.ContractNumber = @contract_number
WHERE MonthPeriod = Format(@service_start_date, N'MMM-yy') -- Not sure what table this is from

DROP TABLE #tmp

另一种方法是使用公用表表达式(CTE)

;WITH CTE AS(
    SELECT SUM(QuantityBilled) as QuantityBilled, ServiceID , TerminalID, ContractID
    FROM dbo.ThruputServiceRendereds WITH(NOLOCK)
    WHERE TransactionCompleteDatetime BETWEEN @service_start_date AND @endDate
    GROUP BY ServiceID
)
UPDATE #IncrementalCreditHeaderResult
SET TotalDeliveredVolume = TSR.QuantityBilled
FROM CTE TSR -- rest should be the same.

第三种选择是使用子查询:

UPDATE #IncrementalCreditHeaderResult
SET TotalDeliveredVolume = TSR.QuantityBilled
FROM (
    SELECT SUM(QuantityBilled) as QuantityBilled, ServiceID , TerminalID, ContractID
    FROM dbo.ThruputServiceRendereds WITH(NOLOCK)
    WHERE TransactionCompleteDatetime BETWEEN @service_start_date AND @endDate
    GROUP BY ServiceID
) TSR  -- rest should be the same.

答案 1 :(得分:0)

这是最简单的方法

    DECLARE @TDV DECIMAL(18,7)
    SELECT @TDV = CAST(SUM(TSR.QuantityBilled) AS DECIMAL(18,7)) FROM dbo.ThruputServiceRendereds TSR WITH(NOLOCK)
    INNER JOIN Services S WITH(NOLOCK) ON S.ServiceId = TSR.ServiceID AND  S.ServiceCode = 'TRAN' AND TSR.TransactionCompleteDatetime BETWEEN @service_start_date AND @endDate
    INNER JOIN Terminals T WITH(NOLOCK) ON T.TerminalID = TSR.TerminalID AND T.TerminalNumber = @terminal_number
    INNER JOIN Contracts C WITH(NOLOCK) ON C.ContractID = TSR.ContractID AND C.ContractNumber = @contract_number

    UPDATE #IncrementalCreditHeaderResult
    SET TotalDeliveredVolume = @TDV
    WHERE MonthPeriod = Format(@service_start_date, N'MMM-yy')