T-SQL reference › GROUP BY error 8120

Fix “Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause”

Msg 8120 means you asked for one row per group, but also asked for a column that could have many different values in that group. SQL Server won’t guess which one you meant.

The error

SELECT status, customer_id, COUNT(*) AS order_count
FROM Orders
GROUP BY status;
-- Msg 8120, Level 16: Column 'Orders.customer_id' is invalid in the select list
-- because it is not contained in either an aggregate function or the GROUP BY clause.

There is one row per status, but each status has many customers. Which customer_id should go on the row? SQL Server refuses to pick. (MySQL and SQLite sometimes do pick one at random, which is worse.)

Fix 1: group by it too

SELECT status, customer_id, COUNT(*) AS order_count
FROM Orders
GROUP BY status, customer_id;

Now there’s a row per status per customer. Right if that’s what you wanted.

Fix 2: aggregate it

SELECT status, COUNT(DISTINCT customer_id) AS customers, COUNT(*) AS order_count
FROM Orders
GROUP BY status;

Fix 3: you forgot GROUP BY entirely

SELECT status, COUNT(*) AS order_count
FROM Orders
GROUP BY status;   -- without this line, COUNT(*) is one total for the whole table
The alias version

GROUP BY size where size is a CASE alias gives a similar error. GROUP BY runs before SELECT, so repeat the CASE expression or put it in a CTE.

Try it on Harbour & Co

Tom Gallagher (Warehouse Lead) needs this now: “This errors and I don’t get why. I just want orders per status.” Write the query, run it, send the results. On the paid plan.

Take the ticket →