Calculate per group with FOREACH
Work out a total per customer, per product or per anything, then group, color or filter your chart by it.
Some questions need two levels at once. "How many of my customers spent over $1,000?" means adding up sales for each customer first, then sorting customers into groups. Your data is usually one row per order, so the per-customer total doesn't exist yet. FOREACH creates it.
FOREACH([Customer], SUM([Sales]))Read it as "for each customer, sum sales." Every row gets its customer's total sales, so an order from a customer who spent $4,200 overall carries 4,200. Because the value sits on every row, you can group by it, color by it, or filter on it like any other field.
Write a FOREACH field
- Open the Create Calculated Field dialog (see Create a calculated field).
- Give the field a name, for example Customer Tier.
- Enter the formula. FOREACH is listed with the other aggregates in the formula editor.
- Save the field. It appears in your field list, ready to drag onto a chart.
FOREACH takes two parts, in this order:
- The group: one field, in brackets. This is the "per what":
[Customer],[Product],[Region]. - The calculation: one aggregate over one field.
SUM,AVG,COUNT,COUNTD,MIN,MAXandMEDIANall work.
Example: tier your customers
Say you run sales ops for a hardware distributor and want to know how many accounts spent more than $1,000. Wrap FOREACH in an IF to turn the total into a label:
IF(FOREACH([Customer], SUM([Sales])) > 1000, "High", "Other")- Save it as Customer Tier.
- Drag Customer Tier onto the X axis. You get two bars, High and Other.
- Put Count Distinct of Customer on the Y axis. Each bar now shows how many customers are in that tier.
FOREACH([Customer], SUM([Sales])) * 1.1 works. FOREACH([Customer], SUM([Sales]) * 1.1) doesn't, because the inside has to be a single aggregate.Count customers, not rows
Counting rows is still a valid question ("how many orders came from High customers?"), so Golden only points it out. Your chart stays as you built it.
When you can skip FOREACH
You don't always have to name the group. If you write IF(SUM([Sales]) > 1000, "High", "Other") and put it on Color, a label, a tooltip or a table, it already works: the chart has grouped your data, so the total is worked out for each bar or row.
When you put that same field on an axis, Golden needs to know the group before it can draw anything. If your chart makes it obvious, with exactly one other grouping field on the chart or a Count Distinct of one field, Golden uses that group for you.
If you put a text-returning field like this on a number axis, the chart explains that there's no height to draw. When the chart has one dimension, it also shows the FOREACH version of your formula to copy into the field. Golden never changes the field for you, because other charts may use it.
What doesn't work yet
- One group field at a time. FOREACH takes a single field. Grouping by Region and Customer together isn't supported.
- Joined tables. On a dataset that joins several tables, you can show a FOREACH field but you can't use it as the axis.
- COUNTD on Amazon Redshift. Redshift can't count distinct values per group this way. Use
COUNTinside the FOREACH, or add the distinct count to your chart as its own measure. - FOREACH inside another total. A formula like
COUNTD(IF(FOREACH(…) > 1000, …))is refused. Put the FOREACH field on the chart instead and use Count Distinct of the field it groups by.