Skip Navigation Links
Home
Articles
SQL Server 2012
SQL Server 2014
SQL Server 2016
FAQ
Practice Test
Tip of the Day : SQL Server Database Design - Twitter Profile and Followers
Error Messages
Home > SQL Server Error Messages > Msg 157 - An aggregate may not appear in the set list of an UPDATE statement.
SQL Server Error Messages - Msg 157 - An aggregate may not appear in the set list of an UPDATE statement.

SQL Server Error Messages - Msg 157

Error Message

Server: Msg 157, Level 15, State 1, Line 1
An aggregate may not appear in the set list of an 
UPDATE statement.

Causes

As the message suggests, this error occurs when you are trying to set one of your columns using the UPDATE statement with a value that uses an aggregate function such as the SUM, MAX or MIN aggregate functions.

To illustrate, let's assume you have the following 2 tables:

CREATE TABLE [dbo].[Account Balance] (
    [Account Number]        VARCHAR(10),
    [Account Balance]       MONEY,
    [Last Transaction Date] DATETIME
)

CREATE TABLE [dbo].[Account Transaction] (
    [Account Number]        VARCHAR(10),
    [Transaction Amount]    MONEY,
    [Transaction Date]      DATETIME
)

The first table contains all the accounts in your company with the current account balance and the last transaction date. The second table contains all the transactions performed on those accounts. You are trying to update the [Account Balance] and [Last Transaction Date] columns of your [dbo].[Account Balance] table using the following UPDATE statement:

UPDATE A
SET [Account Balance] = SUM([Transaction Amount]),
    [Last Transaction Date] = MAX([Transaction Date])
FROM [dbo].[Account Balance] A INNER JOIN [dbo].[Account Transaction] B
  ON A.[Account Number] = B.[Account Number]

Issuing this UPDATE statement will generate the following error message:

Server: Msg 157, Level 15, State 1, Line 2
An aggregate may not appear in the set list of an UPDATE statement.

Solution / Work Around

To update a table with the aggregate values of another table, you have to use a sub-query as can be seen from the following UPDATE statement:

UPDATE A
SET [Account Balance] = B.[Account Balance],
    [Last Transaction Date] = B.[Last Transaction Date]
FROM [dbo].[Account Balance] A INNER JOIN 
(SELECT [Account Number], SUM([Transaction Amount]) AS [Account Balance],
        MAX([Transaction Date]) AS [Last Transaction Date]
 FROM [dbo].[Account Transaction]
 GROUP BY [Account Number]) B
ON A.[Account Number] = B.[Account Number]

Alternatively, you can also use a common-table expression (CTE) instead of a sub-query. Here's how the query will look like using a CTE:

WITH AccountBalanceCTE AS (
    SELECT [Account Number], SUM([Transaction Amount]) AS [Account Balance],
                             MAX([Transaction Date]) AS [Last Transaction Date]
    FROM [dbo].[Account Transaction]
    GROUP BY [Account Number])
UPDATE A
SET [Account Balance]       = B.[Account Balance],
    [Last Transaction Date] = B.[Last Transaction Date]
FROM [dbo].[Account Balance] A INNER JOIN AccountBalanceCTE B
  ON A.[Account Number] = B.[Account Number]
Related Articles :