# Dimensions and filters

> Dimensions are the columns you slice by. Named filters say which rows count. Categories give one word to a way of slicing across source systems.

A metric says what to count. Three other kinds of definition say how to slice it and which rows to count:

- A **dimension** is a column you slice by, such as `customer name` or `issued date`.
- A [category](https://docs.sanda-os.com.au/reference/glossary#category) is one word for a way of slicing that several columns share, such as `region`.
- A named [filter](https://docs.sanda-os.com.au/reference/glossary#filter) is a condition your team says out loud, such as `paid invoices`, written down once.

## Dimensions

"Revenue by region" needs a `region`. A dimension gives a column a name people use, other words for it, and, for a date, a grain and a roll-up.

You do not have to make a dimension of a column to slice by it. In the [workbench](https://docs.sanda-os.com.au/semantic-fluid/query-the-fluid) you can pick any column on the map. A dimension is for the columns people actually ask about, so that a question phrased in your team's words finds the right one.

### Add a dimension

Dimensions live in the list view. Press **List**, open the **dimensions** tab, and press **Add dimension**.

| Field | What to enter | Example |
|---|---|---|
| **Dimension** | The name | `customer name` |
| **Source column** | The column, in full: schema, table, column | `mapping.billing__customers.customer_name` |
| **Type** | Category, Time, Place, Yes / no or Number band | Category |
| **Grain** | For a time dimension, the finest unit | `day` |
| **Rolls up** | For a time dimension, the steps it rolls up through, finest first, separated by commas | `day, month, quarter, year` |
| **Table** | The table the column belongs to. Leave it empty for a dimension that any table carrying the column may use | `customers` |
| **Also called** | Other words, separated by commas | `client, account` |
| **Notes** | What it means to your team | |

You can also ask cherry: "make region a dimension on the customers table". A [learn pass](https://docs.sanda-os.com.au/semantic-fluid/learn) proposes dimensions too.

A column from the loader's own bookkeeping cannot be a dimension. It is not part of what sanda publishes.

### One dimension per column

A column has one dimension. If a column already has one under a different name, sanda refuses the second and says which name it holds:

> “customer city” already names mapping.billing__customers.customer_city. One column is one dimension: rename that one, or add “customer town” as a synonym of it.

A second name for one column is a synonym, and that is where it belongs. This is what stops the workbench listing `customer city` and `customer_city` as two things when they are one.

To rename a dimension, delete it in the list and add it again under the new name. Adding a dimension under its own existing name changes it in place, so to edit one, re-enter every field.

### Time dimensions

Set **Type** to **Time**, give it a **Grain**, and list the steps it rolls up through under **Rolls up**, finest first: `day, month, quarter, year`. "By quarter" then becomes a lookup, not a guess about which date function to use.

In the workbench, a time dimension gets a grouping control: **each row**, **day**, **week**, **month**, **quarter** or **year**. Grouping a column that is not a date is refused with a sentence, not a warehouse error.

### Synonyms

**Also called** words work like the aliases described in [naming rules](https://docs.sanda-os.com.au/semantic-fluid/naming#synonyms-instead-of-second-spellings). A word finds a dimension only if it names exactly one. The workbench's search and the agent's lookups match them, and the agent's full text lists them after "Also called".

## Categories

A dimension names one column. A category names the idea, so it can cover many columns. `region` in your billing system and `ship_region` in your shop would need two dimensions under two names, and nothing tells an agent they are the same question. As one category, `region` covers both, and "by region" works across the two systems.

### Create a category and tag its columns

:::steps
1. **Open categories.** Press **categories** on the rail.
2. **Name it.** Type in **New category** (for example `region` or `channel`) and press **add category**. Press the new category's name to open it.
3. **Say what it means.** Under "What this way of slicing means to your team", write a note and press **save**. The agent reads it beside the column list.
4. **Tick the columns.** **Columns that carry it** is on the left, and a finder on the right lists every column on the map. Search for `region`, `zone` or `state` and tick each column that carries the idea.
:::

You can also tag from a card. Hover over a column, press the tag icon, and tick categories in the dialog, or create a new one there.

A column can carry more than one category, because a `region` column can also be `territory`. Hover over a category in the panel and every column it covers lights up on the map, so you can see that `region` is tagged on three tables and missed on a fourth.

What the agent gets is one instruction: "group by this, and here is every column that means it". A category whose tables are all off the map is left out.

## Named filters

Every other kind says what a column is. None says which rows count. "Approved", "open" and "excluding staff accounts" would otherwise be re-explained in every question, or copied into one metric's condition and left to drift. Name the condition once and use it by name.

### Name a condition

:::steps
1. **Open filters.** Press **filters** on the rail, then **name a condition**. You need a table on the map.
2. **Name it.** For example `approved invoices`.
3. **Write the condition.** In the field that reads "Only rows where", enter a SQL condition over the table's columns, such as `status = 'AUTHORISED' and voided_at is null`.
4. **Pick the table.** The table is required. An unqualified condition means nothing until you know whose `status` it is.
5. **Add other words and notes if you want them.** Then press **save filter**.
:::

The condition must be a single SQL fragment: no semicolon and no comment, up to 1,000 characters.

To change a filter, press it in the list and press **edit**. Saving under the same name replaces it. There is no rename, because nothing builds a filter out of another filter: to rename one, save it under the new name and delete the old one.

### Using a filter

- In the workbench, filters have their own folder. Press one to add it to the question.
- The agent is told that a named filter is your own definition of which rows count, and to use it by name. Its full text gives the condition to put in the `where` clause exactly as written.
- If the filter's table leaves the map, the filter stops applying, and its row in the panel reads "table has gone".

### Three ways to narrow rows

| | Belongs to | Has a name | Use it when |
|---|---|---|---|
| A metric's **only counting rows where** | One metric | No | The condition is part of what that number means |
| A **named filter** | The workspace | Yes | Many questions need the same condition |
| A **condition** in the workbench | One question | No | You want to narrow a single question and move on |

Conditions use a fixed set of operators and named date periods. See [filters](https://docs.sanda-os.com.au/reference/filters).

:::links
- [Metrics](https://docs.sanda-os.com.au/semantic-fluid/metrics): Numbers to slice and narrow.
- [Naming rules](https://docs.sanda-os.com.au/semantic-fluid/naming): What a name is and how synonyms work.
- [Query the fluid](https://docs.sanda-os.com.au/semantic-fluid/query-the-fluid): Use dimensions, filters and conditions together.
:::
