{
    "slug": "mysql_group_by",
    "term": "MySQL GROUP BY and Aggregates",
    "category": "database",
    "difficulty": "intermediate",
    "short": "GROUP BY collapses rows with matching column values into one — aggregate functions (COUNT, SUM, AVG, MAX, MIN) compute values per group.",
    "long": "GROUP BY is used with aggregate functions to summarise data. MySQL's ONLY_FULL_GROUP_BY mode (default since 5.7) requires all SELECT columns to be in GROUP BY or wrapped in an aggregate — preventing non-deterministic results. HAVING filters groups after aggregation; WHERE filters rows before aggregation. ROLLUP adds subtotals. Window functions (MySQL 8) provide aggregation without collapsing rows.",
    "aliases": [
        "GROUP BY MySQL",
        "aggregate functions MySQL",
        "HAVING vs WHERE",
        "COUNT SUM AVG MySQL"
    ],
    "tags": [
        "mysql",
        "database",
        "sql"
    ],
    "misconception": "You can SELECT any column when using GROUP BY. Without ONLY_FULL_GROUP_BY enabled, MySQL silently returns a random value for un-aggregated, un-grouped columns.",
    "why_it_matters": "Selecting non-aggregated columns without ONLY_FULL_GROUP_BY returns a random value from the group — a silent correctness bug that produces different results on different MySQL versions.",
    "common_mistakes": [
        "Using WHERE to filter aggregate results instead of HAVING — WHERE runs before aggregation.",
        "Selecting non-aggregated columns not in GROUP BY — non-deterministic on MySQL permissive mode.",
        "GROUP BY on an unindexed column — triggers filesort in the EXPLAIN Extra column."
    ],
    "when_to_use": [
        "Use GROUP BY with COUNT/SUM/AVG for reporting and analytics queries.",
        "Use HAVING to filter groups — e.g. users with more than 5 orders."
    ],
    "avoid_when": [
        "Do not use GROUP BY on an unindexed column for large tables — add an index to avoid filesort.",
        "Do not use GROUP BY as a workaround for DISTINCT — they have different semantics."
    ],
    "related": [
        "mysql_joins",
        "mysql_subqueries",
        "mysql_indexes_explained"
    ],
    "prerequisites": [
        "mysql_joins"
    ],
    "refs": [
        "https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html"
    ],
    "bad_code": "-- ONLY_FULL_GROUP_BY error in MySQL 5.7+\nSELECT user_id, email, COUNT(*) AS orders\nFROM orders\nGROUP BY user_id; -- email not in GROUP BY or aggregate",
    "good_code": "SELECT user_id,\n       COUNT(*)        AS order_count,\n       SUM(total)      AS revenue,\n       MAX(created_at) AS last_order\nFROM orders\nGROUP BY user_id\nHAVING COUNT(*) > 5\nORDER BY revenue DESC;",
    "quick_fix": "Every column in SELECT must appear in GROUP BY or be wrapped in an aggregate function — use HAVING to filter on aggregate results",
    "effort": "low",
    "created": "2026-03-31",
    "updated": "2026-03-31",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/mysql_group_by",
        "html_url": "https://codeclaritylab.com/glossary/mysql_group_by",
        "json_url": "https://codeclaritylab.com/glossary/mysql_group_by.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[MySQL GROUP BY and Aggregates](https://codeclaritylab.com/glossary/mysql_group_by) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/mysql_group_by"
            }
        }
    }
}