Overview
Looker builds every report from three kinds of fields: dimensions, measures, and table calculations. They look similar in the field picker, but they behave very differently — and most Looker errors ("field does not exist," pivots returning null, averages looking identical on every row) trace back to mixing these up. This article defines each one and gives a quick way to tell them apart.
1. Dimension
What it is: An attribute of a single row. A dimension describes something — it doesn't add numbers together.
Grain: Row-level. One value per record.
Examples:
- Case Number
- Case Grossed By (user name)
- Date Collected
- CPT Code
- Weekday/Weekend Flag (a Custom Dimension built with an
if()formula)
How to spot one: If you can put it in the "rows" or "group by" position of a report and it changes how results are broken out (not just how they're totaled), it's a dimension. Dimensions can be filtered on directly and used to group/pivot other fields.
2. Measure
What it is: An aggregation across a group of rows — a number computed by summing, counting, or averaging many records together.
Grain: Group-level. One value per group of rows (or one value for the whole result set if there's no dimension to group by).
Examples:
- Case Count (a
count()) - Avg Case Duration (a
sum()/count()Custom Measure) - Distinct Days (a Count Distinct Custom Measure)
- Total CPT Count
How to spot one: If the field's value only makes sense in the context of "per what group?" — and changes depending on which dimensions are on the report — it's a measure. Measures cannot be used to group/pivot other fields.
3. Table Calculation
What it is: A formula built in the Explore UI, computed after Looker has already returned the dimension and measure results. It operates on the result set you're looking at, not on the underlying data model.
Grain: Whatever the rows in front of you already are — it doesn't change grain, it just does math on what's already there.
Examples from our reports:
- TAT bucket label:
if(${np_case_tat.tatreceived_to_finalized_bus_days} <= 3, "<=3 Days", ">3 Days") - Collect-to-accession formatted display ("3h 16m 30s")
- Overtime seconds / Time Over 24hrs flag
- CPT code ratio (stains ÷ base code)
How to spot one: Built via Custom Fields → Table Calculation in the Explore itself (not saved to the data model), and it disappears if you rebuild the query from scratch in a new Explore.
Side-by-side comparison
| Dimension | Measure | Table Calculation | |
|---|---|---|---|
| Grain | Row-level | Group-level (aggregated) | Post-query, on the result set |
| Can be used as an Explore filter? | Yes | Yes (filters the aggregate) | No, in this Looker instance |
| Can be pivoted/grouped on? | Yes | No | Unreliable — often returns nulls if it's based on a measure-type field |
| Reusable across Explores/Looks? | Yes, if built as a Custom Dimension or LookML | Yes, if built as a Custom Measure or LookML | No — lives only in the Look it was built in |
| Access needed to build | Create Custom Fields permission (or LookML developer for a permanent one) | Create Custom Fields permission (or LookML developer for a permanent one) | None — available to anyone in the Explore UI |
| Respects row groups when averaging per category? | N/A | Yes — a Custom Measure average is correct per dimension group | No — a table calc "average" computes across the entire result set, so it shows the same value on every row instead of one value per group |
The mistake this prevents
The most common error we've hit: trying to build a per-group average (e.g. average turnaround time per grosser) as a table calculation. Because table calculations aggregate across the whole result set rather than within each group, every row shows the identical global average instead of each user's own average. The fix is always the same — build it as a Custom Measure instead, which does respect grouping by whatever dimension is on the report (see the Grossing Productivity Report article for the full build).
Quick decision guide
- Need to describe or group rows? → Dimension
- Need a number that aggregates many rows, and it must respect whatever dimension groups the report by? → Measure
- Need to reformat, bucket, or do quick math on numbers already in front of you, just for this one report, with no developer access? → Table Calculation
- Need it to work as a filter, or be reused across multiple Looks? → Must be a Dimension or Measure, not a table calculation