# Summarize

> Group a list and work out a count, total, average, smallest or largest for each group.

**Summarize** turns a list into grouped results. Pick what to group by, then say what to work out for each group: a count, a total, an average, the smallest or the largest.

> Dock: Data · Change · Takes: a list · Returns: a list of groups

It answers the questions that otherwise need code. Revenue per account manager, tickets per priority, orders per region.

> **Simple total or average without grouping?** You can calculate a single total, average, count, or min/max directly inside field tokens using [Data Transformation](/build/core-concepts/data-transformation):
> - Sum of record property: `{{ 3.deals | pluck:amount | total }}`
> - Average deal size: `{{ 3.deals | pluck:amount | average }}`
> - Largest sale: `{{ 3.deals | pluck:amount | largest }}`
> - Count of items: `{{ 3.deals | count }}`
>
> Use the **Summarize** canvas step when you need to group data by dimensions (e.g. revenue grouped by account manager or ticket counts per status).

## Setting it up

### Add the step

Open **Tools** in the dock and choose **Summarize**.

### Point it at a list

**List to summarize** takes a reference to a list an earlier step produced, for example `{{ 3.result }}`. Insert it from the data icon rather than typing it.

### Choose how to group

**Group by** takes the field whose values become the groups: `region`, `owner`, `priority`. Add more than one row to group by a combination.

Leave it empty to treat the whole list as one group. That is how you total a list without splitting it.

### Say what to work out

**Work out** takes one row per number you want. Each row picks an operation and what to work on: a field of each record, or each whole item. Count needs neither.

| Operation           | What it gives you                                                 |
| ------------------- | ----------------------------------------------------------------- |
| **Count**           | How many records are in the group                                 |
| **Count unique**    | How many different values a field has                             |
| **Sum**             | The total of a numeric field                                      |
| **Average**         | The mean of a numeric field                                       |
| **Smallest**        | The lowest value                                                  |
| **Largest**         | The highest value                                                 |
| **List the values** | Every value of that field in the group, as a list                 |
| **Join the values** | The same values as one piece of text, with a separator you choose |

The last two answer a different question from the rest. Instead of a number
about the group, they hand you back what is in it: every email address in a
region, say, or those addresses joined by a comma, ready for a To field.

## Summarizing a list of plain values

When the list holds plain values rather than records, a list of amounts, say, set **Work on** to **Each whole item**. The panel pre-selects it when the sample list holds plain values. Sum, Average, Smallest and Largest use numbers only; a blank or non-number item follows **If a field is missing**.

The output column is named after the operation alone, so a whole-item Sum arrives as `{{ N.groups.0.sum }}`.

**Group by** always takes a field. To total a list of plain values, leave Group by empty and work on each whole item.

## What it passes on

**The result is always a list under `groups`**, even when everything landed in one group. That way a reference written against one grouping still works when you change the grouping later.

| Reference            | What it holds             |
| -------------------- | ------------------------- |
| `{{ N.groups }}`     | One entry per group       |
| `{{ N.groupCount }}` | How many groups there are |

Each entry carries the fields you grouped by, plus one column per row of **Work out**. The column is named after the operation and the field, so a Sum of `amount` arrives as `sum_amount`:

```
{{ 5.groups.0.region }}       first group's region
{{ 5.groups.0.sum_amount }}   that group's total
{{ 5.groups.0.count }}        how many records it holds
```

Because `groups` is a list, a [Repeater](/build/action-steps/loops) can run over it: one Slack message per region, for example.

**Groups come out in the order they first appear** in the input list, not sorted.

## How values are counted

This is the part worth reading before you trust a total.

**A missing value is missing, not zero.** Ten rows where one has no amount would average 10% low if the blank counted as zero, and nothing in the result would say so. The same applies to a value that is not a number after conversion: `"n/a"`, `true`, or an empty object.

**If a field is missing** decides what happens:

- **Report** flags it, so you find out.
- **Skip** leaves those records out of that calculation.

Both are defensible; the point is that you choose rather than the step choosing for you.

**Numbers written as text still add up.** A list arriving through `{{ 3.rows }}` often has amounts like `"1200"` rather than `1200`, because references are resolved as text. Summarize converts them, so a total is not silently zero.

**Money does not drift.** Totals accumulate exactly, so `0.1 + 0.2` is `0.3`.

**Decimal places** rounds the results. Set it to 2 for currency.

## Limits

- **Two rows cannot write the same column.** Two Sums of `amount` would both be `sum_amount`, so the step reports the clash instead of one silently overwriting the other.
- **A record missing its group-by field** never lands in a group called "undefined". It follows the same **If a field is missing** setting.

## Examples to copy

### Revenue per account manager

**List:** `{{ 3.deals }}` · **Group by:** `owner` · **Work out:** Sum of `amount`, and Count.

Gives one entry per owner with `sum_amount` and `count`. Follow it with a Repeater over `{{ N.groups }}` to send each manager their own figure.

### Tickets per priority, as one message

**List:** `{{ 2.tickets }}` · **Group by:** `priority` · **Work out:** Count.

Then reference the groups directly in a Slack message rather than looping.

### A single total, no grouping

**List:** `{{ 4.invoices }}` · **Group by:** empty · **Work out:** Sum of `total`.

One group, reached as `{{ N.groups.0.sum_total }}`.

## What's Next?

- Run over each group with [Repeater](/build/action-steps/loops).
- [AI Data Transform](/build/ai-features/ai-transform) — for pulling values out of text that has no fixed shape.
- Reshape records before summarising them with [Change fields](/build/action-steps/change-fields).
