| 
                                    
                                        |  | SQL Server Error Messages - Msg 147Error MessageServer: Msg 147, Level 15, State 1, Line 1
An aggregate may not appear in the WHERE clause unless
it is in a subquery contained in a HAVING clause or a
select list, and the column being aggregated is an
outer reference. CausesThis error occurs when you include an aggregate function such as MAX,MIN,AVGorCOUNTin yourWHEREclause.  To illustrate, let's say you have the following table that contains all your customers: |  CREATE TABLE [dbo].[Customers] (
    [CustomerID]    INT,
    [FirstName]     VARCHAR(50),
    [LastName]      VARCHAR(50)
)
 From this table, you want to determine the duplicate records based on the customer's first name and last name by issuing the following SELECTstatement: SELECT [FirstName], [LastName], COUNT(*)
FROM [dbo].[Customers]
WHERE COUNT(*) > 1
GROUP BY [FirstName], [LastName]
 Issuing this SELECTstatement will generate the following error message: Server: Msg 147, Level 15, State 1, Line 3
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING
clause or a select list, and the column being aggregated is an outer reference.
 As another example, let's say you have the following table that contains the salaries of your employees: CREATE TABLE [dbo].[EmployeeSalary] (
    [EmployeeID]        INT,
    [Salary]            MONEY
)
 From this table, you want to generate a list of employees whose salary is higher than the average salary of all employees.  To accomplish this requirement, you issued the following SELECTstatement: SELECT [EmployeeID], [Salary]
FROM [dbo].[EmployeeSalary]
WHERE [Salary] >= AVG([Salary])
 Issuing this SELECTstatement, just like the first one, will also generate the same error message: Server: Msg 147, Level 15, State 1, Line 3
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING
clause or a select list, and the column being aggregated is an outer reference.
 Solution / Work AroundIf you need to filter out the records from your SELECTstatement with the values from an aggregate function, you have to specify the condition in theHAVINGclause of theSELECTstatement and not in theWHEREclause. For the first example above, to get the duplicate customer records based on the first name and last name, the correct SELECTstatement is as follows: SELECT [FirstName], [LastName], COUNT(*)
FROM [dbo].[Customers]
GROUP BY [FirstName], [LastName]
HAVING COUNT(*) > 1
 The only difference between this corrected SELECTstatement and the one above is the moving of theCOUNT(*) > 1condition from theWHEREclause to theHAVINGclause because it is using an aggregate function, in this case theCOUNTaggregate function. For the second example above, you will need to use a sub-query to get the list of employees whose salary is higher than the average salary of all employees: SELECT [EmployeeID], [Salary]
FROM [dbo].[EmployeeSalary]
WHERE [Salary] >= (SELECT AVG([Salary])
                   FROM [dbo].[EmployeeSalary])
 |