I want to filter a table showing only the rows where total is between ± 3 standard deviations from the average.
The query I’m using is this:
SELECT * FROM AccountsDatabase WHERE total > (AVG(total) + STDEVP(total) * -3) AND total < (AVG(total) + STDEVP(total) * +3)`
But I’m getting the error:
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.
Advertisement
Answer
Try something like this. I have added some sample data as your question has not given any data and schemas. You need to use group by clause when you use Aggregate functions in our queries. I suggest you to refer to Group by and aggregate functions in SQL server.
Sample data scripts:
SELECT * INTO #SRC_Data FROM ( SELECT 0 AS A, 8.0 AS B,1 AS C UNION ALL SELECT 1, 8.0,7 UNION ALL SELECT 2, 6.0,3 UNION ALL SELECT 3,9.0,4 UNION ALL SELECT 4, 10.0,6 UNION ALL SELECT 5, 11.0,2 ) AS A
1st way: You need to use GROUP BY and HAVING when use Aggregate functions in filters. Having can filter by groups.
SELECT * FROM #SRC_Data GROUP BY A, B, C HAVING A >= (AVG(A) + STDEVP(A) * -3) AND A < (AVG(A) + STDEVP(A) * 3)
2nd way: Use Aggregations as a sub query. in that case you don’t need to use group by or having as you use subquery in where clause.
SELECT * FROM #SRC_Data WHERE A > ( SELECT AVG(B) FROM #SRC_Data ) + ( SELECT STDEVP(B) * -3 FROM #SRC_Data) AND A < (SELECT AVG(B) FROM #SRC_Data ) + ( SELECT STDEVP(B) * 3 FROM #SRC_Data) DROP TABLE #SRC_Data