GROUP BY check

✓ functional

A grouped query that selects a column it neither groups nor aggregates is underlined as you type, with the reason and a one-click fix.

When a query aggregates - COUNT, SUM, MAX and friends - or has a GROUP BY, every column it selects must either be grouped or sit inside an aggregate. Otherwise the database cannot know which of the group's values to show, and SQL Server stops with error 8120. SQLly catches this while you type, before you run anything.

SELECT
    Category,        → ✖ not grouped or aggregated
    COUNT(1)
from
    Shared.Settings

Run that on SQL Server and you get Column 'Shared.Settings.Category' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. In SQLly, Category is underlined instead, the moment the query takes that shape.

Why it is flagged, and the fix

Hover the underlined column and a popup explains the problem: the query groups its rows, so each result row stands for a whole group, and the column can differ from row to row within a group. Below the explanation is a Fix this link that names the columns it will add. Click it and SQLly writes them into the GROUP BY, as a single edit you can undo:

-- after "Fix this: add Category to GROUP BY"
SELECT
    Category,
    COUNT(1)
from
    Shared.Settings
group by
    Category
  • No GROUP BY yet: the clause is written after FROM and WHERE, ahead of any HAVING or ORDER BY. It follows the query's own layout - on its own lines and indented when your FROM is, inline when the query is on one line - and the keyword case your FROM uses.
  • A GROUP BY already there: the missing columns are appended to it, on new lines if the list is already split across lines.
  • Several missing columns: each one is underlined, and the fix adds them all at once.
  • Columns are added exactly as you wrote them in the select list, so s.Category stays alias-qualified.

The same finding is listed when you run Validate SQL (⌘⇧V).

Completing inside GROUP BY

Completion uses the same check. With the caret in a GROUP BY list, the columns it still needs come first, marked ● required by SELECT and drawn bold, followed by the rest of the query's columns. Tables, views, and procedures are not offered there. Once a column is grouped it is no longer marked required.

What it checks, and what it leaves alone

The check is deliberately cautious: it only flags a select-list item that is a plain column reference, such as Category, s.Category, or [dbo].[T].[Category]. A column counts as grouped when any GROUP BY key names it, whether qualified, bare, or by the select item's alias. It stays quiet on expressions like UPPER(Name), on *, literals, variables, subqueries, and window functions such as COUNT(*) OVER (...). Each subquery, CTE body, and UNION branch is checked on its own.

How strict depends on the engine. SQL Server, PostgreSQL, and Oracle always reject an ungrouped column, so it is marked as an error. On MySQL and MariaDB it depends on the server's ONLY_FULL_GROUP_BY setting, so it is a warning. SQLite allows it and picks a value from the group, so SQLly says nothing there.