Ever seen the error “An aggregate may not appear in the set list of an UPDATE statement” when working with SQL Server? I ran into this one recently after trying to put a COUNT in an UPDATE statement. I was rewriting some legacy code to use a stored procedure, and it turned out to be the perfect case for a Temporary Table.
Instead of boring you with a work scenario, let’s take a simpler one that uses the AdventureWorks database. This example will create a list of sales people, total order count for each person, and store this list a single table variable to be used as the final data table.
Should be three simple steps right?
1. Create @Table variable
[sql]
DECLARE @SalesPeople TABLE
(
EmployeeID int NOT NULL,
SalesPersonID int NOT NULL,
FullName varchar(200) NOT NULL,
Title varchar(200) NOT NULL,
sales_count int NULL default 0
)
[/sql]
2. INSERT sales people into @Table
[sql]
— HACKISH : Match SalesPersonID to EmployeeID, and fill @SalesPeople
INSERT INTO @SalesPeople
( EmployeeID, SalesPersonID, FullName, Title )
SELECT e.EmployeeID, sp.SalesPersonID,
c.FirstName + ‘ ‘ + c.LastName as FullName,
e.Title
FROM Sales.SalesPerson sp,
HumanResources.Employee e,
Person.Contact c
WHERE sp.SalesPersonID = e.EmployeeID
AND e.ContactID = c.ContactID
[/sql]
3. UPDATE @Table with COUNT
[sql]
UPDATE @SalesPeople
SET
sales_count = COUNT( soh.SalesOrderID )
FROM @SalesPeople sp, Sales.SalesOrderHeader soh
WHERE EXISTS (
SELECT DISTINCT SalesPersonID FROM @SalesPeople WHERE SalesPersonID = soh.SalesPersonID
)
AND sp.SalesPersonID = soh.SalesPersonID
[/sql]
The third step is where the original error comes in, so let’s update this to four steps and see how a Table Variable gets through this.
1 & 2 – Repeat from above
3. Create Table Variable of order counts
[sql]
SELECT soh.SalesPersonID, COUNT( soh.SalesOrderID ) AS sales_count
INTO #SalesOrderCounts
FROM Sales.SalesOrderHeader soh
WHERE EXISTS (
SELECT DISTINCT SalesPersonID FROM @SalesPeople WHERE SalesPersonID = soh.SalesPersonID
)
GROUP BY soh.SalesPersonID
[/sql]
4. Update @Table with order counts
[sql]
UPDATE @SalesPeople
SET sales_count = tmp.sales_count
FROM @SalesPeople sp, #SalesOrderCounts tmp
WHERE sp.SalesPersonID = tmp.SalesPersonID
[/sql]
And here’s the full script from start to finish with the table variable in use.
[sql]
— Master table of sales people
DECLARE @SalesPeople TABLE
(
EmployeeID int NOT NULL,
SalesPersonID int NOT NULL,
FullName varchar(200) NOT NULL,
Title varchar(200) NOT NULL,
sales_count int NULL default 0
)
— Match SalesPersonID to EmployeeID, and fill @SalesPeople
INSERT INTO @SalesPeople
( EmployeeID, SalesPersonID, FullName, Title )
SELECT e.EmployeeID, sp.SalesPersonID,
c.FirstName + ‘ ‘ + c.LastName as FullName,
e.Title
FROM Sales.SalesPerson sp, HumanResources.Employee e, Person.Contact c
WHERE sp.SalesPersonID = e.EmployeeID
AND e.ContactID = c.ContactID
— put sales counts into the other kind of #tableVariable
SELECT soh.SalesPersonID, COUNT( soh.SalesOrderID ) AS sales_count
INTO #SalesOrderCounts
FROM Sales.SalesOrderHeader soh
WHERE EXISTS (
SELECT DISTINCT SalesPersonID FROM @SalesPeople WHERE SalesPersonID = soh.SalesPersonID
)
GROUP BY soh.SalesPersonID
— Update our master @table with data from #tableVariable
UPDATE @SalesPeople
SET sales_count = tmp.sales_count
FROM @SalesPeople sp, #SalesOrderCounts tmp
WHERE sp.SalesPersonID = tmp.SalesPersonID
— dump the results
SELECT FullName, Title, sales_count
FROM @SalesPeople
— cleanup
drop table #SalesOrderCounts
[/sql]













