---
cuppy_hub: salesforce
cuppy_path: reference/official/data360/data-cloud-query-guide/references/dc-sql-reference/select-group-by.md
cuppy_section: docs
cuppy_doc: KPH0-XX71
cuppy_doc_uuid: 382238ca-a183-4e4c-b39e-73d9d95fe1aa
cuppy_permalink: https://cuppy.io/salesforce/d/KPH0-XX71
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/salesforce/docs/reference/official/data360/data-cloud-query-guide/references/dc-sql-reference/select-group-by
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 7c3a8d17f63fd3d6b8fde3e2a80edd1b117e2fc277b7510d4573b6d00e038cb3
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---

> Mirror of <https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/dc-sql-reference/select-group-by.html> (Salesforce, Data 360 Query Guide), read 2026-10-23. Salesforce's own page is the authority; this copy exists because that site refuses non-browser readers.

## `GROUP BY` Clause

Use `GROUP BY` to combine rows that have the same values. Aggregate functions then calculate one result for each group. See [Aggregate Functions](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/dc-sql-reference/aggregate.html).

`grouping_element` can be one of:

For each `<grouping_element>`, use one of these values.

*   **Input column name:** Groups rows by values in a source column.
*   **Output column name:** Groups rows by a named column in the `SELECT` list.
*   **Output column position:** Groups rows by the column’s left-to-right position in the `SELECT` list.
*   **Expression based on input columns:** Groups rows by a calculated value.
*   **Empty grouping set `()`:** Combines all rows into one group.

If a name matches both an input column and an output column, `GROUP BY` uses the input column.

When you use `GROUP BY` or an aggregate function, every selected column must be either:

*   Included in the grouping values.
*   Used in an aggregate function.

Data 360 SQL calculates aggregate functions before it calculates scalar expressions in the `HAVING` clause or `SELECT` list.

`ALL` has two meanings in a `GROUP BY` clause.

*   `GROUP BY ALL` with no grouping list automatically groups on the non-aggregate values in the `SELECT` list.
*   `ALL` before an explicit grouping list retains duplicate grouping sets. This behavior is the default. Use `DISTINCT` to remove duplicate grouping sets.

Use `GROUP BY ALL` to group on every non-aggregate value in the `SELECT` list without repeating those values in the `GROUP BY` clause. An aggregate function, such as `sum()` or `count()`, calculates one value for each group. `GROUP BY ALL` doesn’t group on aggregate results.

`GROUP BY ALL` follows these rules.

*   **Only aggregate functions selected:** All rows form one group, the same as with `GROUP BY ()`.
*   **No aggregate functions selected:** The query groups on every selected value. The result contains the same rows as `SELECT DISTINCT` for those values.
*   **Expression selected:** The complete expression is one grouping value. For example, `a * b` is one grouping value, not separate groups for `a` and `b`.
*   **Column used in multiple selected expressions:** Data 360 SQL finds all grouping values before it checks each selected expression. Selecting a column by itself can group that column when it’s also used inside another selected expression.
*   **`SELECT *` used:** The query groups on every column returned by `*`.

Each example uses a common table expression and `VALUES` list to provide the input rows.

This query groups by `a`, the only selected value that isn’t calculated by an aggregate function.

This query is equivalent to the longer form.

Output:

This query has no aggregate functions, so it groups on both selected columns. The result contains the same rows as `SELECT DISTINCT a, b`.

Output:

This query groups on the result of `a * b`, not on `a` and `b` separately. The rows `(1, 20)` and `(2, 10)` both produce `20`, so they belong to the same group.

Output:

This query selects only aggregate results. Because there are no other selected values to group on, all rows form one group, and the query returns one row.

Output:

This query causes an error. Data 360 SQL doesn’t group on `a + sum(c)` because the expression contains the aggregate function `sum()`. As a result, column `a` isn’t grouped.

Error:

This query works because selecting `a` by itself adds `a` to the group. The query can then use `a` in the expression `a + sum(c)`.

Output:

Use grouping sets to calculate aggregates for several combinations of columns in one query. Data 360 SQL creates the groups after it processes the `FROM` and `WHERE` clauses, then calculates the aggregates for each group.

Each item in `GROUPING SETS` defines one set of columns or expressions to group by.

*   An empty grouping set `()` combines all rows into one group.
*   A column or expression that isn’t part of a grouping set has a null value in rows produced for that set.
*   To identify the grouping set that produced a row, use the [GROUPING function](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/dc-sql-reference/grouping.html).

By default, `GROUP BY` retains duplicate grouping sets. You can add `ALL` before an explicit grouping list to specify this behavior or add `DISTINCT` to remove duplicate grouping sets.

Use `ROLLUP` or `CUBE` instead of listing common grouping-set combinations individually.

| Construct | Grouping Sets Generated | Common Use |
| --- | --- | --- |
| `ROLLUP` | The full list, each left-to-right prefix, and the empty list. | Analyze hierarchical data and subtotals. |
| `CUBE` | Every possible subset of the list, including the empty list. | Analyze every combination of dimensions. |

An element in `ROLLUP` or `CUBE` can be an expression or a parenthesized sublist. Data 360 SQL treats a parenthesized sublist as one unit when it generates grouping sets.

You can use `ROLLUP` and `CUBE` directly in `GROUP BY` or inside `GROUPING SETS`. When a `GROUP BY` clause contains multiple grouping items, Data 360 SQL generates the cross product of those items.

This example shows a simple `ROLLUP` and its equivalent `GROUPING SETS`.

This example shows a simple `CUBE` and its equivalent `GROUPING SETS`.

These examples show how parenthesized sublists stay together when Data 360 SQL expands `CUBE` and `ROLLUP`.

This example shows the equivalent `GROUPING SETS` for `CUBE` if there are multiple grouping items.

If you provide multiple grouping items together, the final set of grouping sets can contain duplicates. This example shows a `ROLLUP` with duplicate values in the equivalent `GROUPING SETS`.

To remove duplicates, use the `DISTINCT` clause on the `GROUP BY`. This example shows a `DISTINCT``ROLLUP` and its equivalent `GROUPING SETS`.

This example shows the use of `GROUPING SETS` for the table `items_sold` that describes the brands, sizes, and number of items sold.

`items_sold`:

Output:


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 376 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/salesforce/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
