Study guide
4.4 Aggregation Rules, Granularity & Dealing with the Asterisk (ATTR)
Salesforce Certified Tableau Data Analyst Exam
Track your progress as you read
Finished sections get a check mark.
1 Chapter 1: Connecting to Data & The Logical Data Model
1.1 Data Connections: Live Connections vs. Hyper Extracts 1.2 The Tableau Data Model: Relationships vs. Physical Joins 1.3 Combining Data: Data Blending vs. Cross-Database Joins
2 Chapter 2: Tableau Prep Builder & Data Wrangling
2.1 Tableau Prep Architecture & Data Cleaning 2.2 Reshaping Data in Prep: Pivots, Splits & Wildcard Unions 2.3 Joins, Aggregations & Output Destinations in Prep
3 Chapter 3: Data Quality, Metadata & Field Configuration
3.1 Data Types, Roles, Organization & Default Properties 3.2 In-Desktop Data Cleaning: Splits, Data Interpreter & Source Replacement 3.3 Managing Slowly Changing Dimensions & Data Quality Warnings
4 Chapter 4: Tableau Fundamentals & Calculations
4.1 Dimensions vs. Measures & Discrete vs. Continuous 4.2 Mastering Dates: Discrete Date Parts vs. Continuous Date Truncations 4.3 Calculations: Logic, Strings, Nulls & Type Conversion 4.4 Aggregation Rules, Granularity & Dealing with the Asterisk (ATTR)
5 Chapter 5: Level of Detail (LOD) Expressions
5.1 Level of Detail Architecture & Scoping Syntax 5.2 FIXED LOD Expressions: Scoping & Baseline Benchmarks 5.3 INCLUDE & EXCLUDE LOD Expressions: Dynamic Granularity 5.4 Real-World LOD Patterns: Cohorts, First/Last Dates & Binning
6 Chapter 6: Table Calculations & Directionality
6.1 Table Calculation Mechanics: Addressing vs. Partitioning 6.2 Essential Table Calculations: Running, Window & Percent of Total 6.3 Navigation & Ranking Functions: LOOKUP, INDEX & RANK 6.4 Secondary & Nested Table Calculations: Multi-Level Scoping
7 Chapter 7: Statistical Analytics, Filtering & Order of Operations
7.1 The Tableau Order of Operations: From Extract to Display Filters 7.2 Sets, Set Actions & Combined Sets vs. Groups 7.3 Parameters, Parameter Actions & Dynamic What-If Analysis 7.4 Analytics Pane: Totals, References, Trends & Forecasts
8 Chapter 8: Chart Types & Comparative Visualizations
8.1 Comparison Visualizations: Bar Charts, Highlight Tables & Bullet Graphs 8.2 Part-to-Whole & Correlation Charts: Treemaps, Scatter Plots & Bubbles 8.3 Trend & Distribution Visualizations: Dual-Axis, Combos & Histograms
9 Chapter 9: Advanced Visualizations & Spatial Analysis
9.1 Specialized Visualizations: Waterfall, Gantt, Sparklines & Bump Charts 9.2 Spatial Data & Mapping: Geographic Layers & Spatial Functions 9.3 Visual Polish: Custom Palettes, Annotations & Viz in Tooltip
10 Chapter 10: Dashboard Design & Interactive Actions
10.1 Dashboard Layout, Devices & Visibility 10.2 Filter, Highlight & URL Actions 10.3 Advanced Interactivity: Parameter, Set & Navigation Actions 10.4 Stories & Visual Storytelling: Sequencing Analytical Narratives
11 Chapter 11: Tableau Server & Cloud: Architecture & Publishing
11.1 Tableau Server & Cloud: Sites, Projects, Roles & Permissions 11.2 Publishing Workbooks, Data Sources & Flows
12 Chapter 12: Data Governance, Security & Operations
12.1 Certification, Data Quality, Lineage & Permissions 12.2 Row-Level Security, Schedules, Subscriptions & Alerts
4.4 Aggregation Rules, Granularity & Dealing with the Asterisk (ATTR)
Key Takeaways Explain This Topic AI
Row-level calculations execute row-by-row before aggregation; aggregate calculations execute across groups of rows defined by the visualization's level of detail.
Ratio grain follows the business definition: SUM([Profit]) / SUM([Sales]) returns overall margin, while AVG([Profit] / [Sales]) returns an unweighted average of row margins.
The error 'Cannot mix aggregate and non-aggregate arguments' occurs when combining an unaggregated row-level field and an aggregate within the same scalar operation.
COUNT() counts all non-null records and is additive and fast, whereas COUNTD() calculates unique distinct values, is non-additive, and incurs heavy computational overhead.
The Attribute function ATTR() evaluates IF MIN([field]) = MAX([field]) THEN MIN([field]) ELSE '*' END, and resolving an asterisk requires adding the field to Detail, altering aggregation to MIN/MAX, or using Relationships.
Last updated: September 2026
4.4 Aggregation Rules, Granularity & Dealing with the Asterisk (ATTR)
Tableau's calculation engine operates on a strict hierarchy of data granularity. Every calculation in Tableau is compiled and executed at one of two fundamental computation levels: Row-Level (Unaggregated) or Aggregate . Failing to understand the boundary between these two computation tiers is the leading cause of broken formulas, calculation compiler errors, and mathematically flawed dashboard metrics.
Furthermore, when Tableau aggregates dimensional attributes or evaluates secondary blended data sources, it invokes the Attribute ( ATTR ) function. Understanding how ATTR() operates, why it generates the infamous asterisk ( * ), and how to resolve it is a cornerstone topic on the Salesforce Certified Tableau Data Analyst exam.
Row-Level Calculations vs. Aggregate Calculations
The fundamental distinction between row-level and aggregate calculations lies in when and where the computation occurs relative to the visualization's Level of Detail (LOD): ROW-LEVEL CALCULATION: [Row 1: Sales - Cost] ---> [Row 2: Sales - Cost] ---> Then Aggregated in Viz
- AGGREGATE CALCULATION: SUM([Sales]) across group / SUM([Cost]) across group ---> Computed at Viz Grain
- 1. Row-Level (Unaggregated) Calculations
Execution: Evaluated on every single transactional row in the underlying database before any summary aggregation takes place.
Syntax Example: [Sales] - [Cost] or [First Name] + ' ' + [Last Name] or [Order Date] + 7 .
Data Pane Representation: Appears in the Data pane with an unaggregated symbol ( # or Abc ). When dragged onto a shelf, Tableau wraps it in a default aggregation (e.g., SUM([Profit_Margin_Row]) ).
2. Aggregate Calculations
Execution: Evaluated across the aggregated sums, averages, or counts of records belonging to each mark in the visualization. The grouping is determined dynamically by the dimensions present on Rows, Columns, and Detail shelves.
Syntax Example: SUM([Profit]) / SUM([Sales]) or AVG([Discount]) * 100 .
Data Pane Representation: Appears in the Data pane with an AGG indicator preceding the field name. When dragged onto a shelf, it displays as AGG([Profit Ratio]) and cannot be re-aggregated with SUM or AVG .
Choosing the Correct Ratio Grain
One of the most dangerous and common errors in analytics is calculating a ratio at the row level and then averaging it on the canvas. Consider a simple dataset with two transactions in a region:
- Transaction Sales Profit Row-Level Profit Ratio ( [Profit] / [Sales] )
- Transaction 1 $100 $50 50.0% ( $50 / $100 )
- Transaction 2 $10,000 $1,000 10.0% ( $1,000 / $10,000 )
- Total / Overall $10,100 $1,050 10.4% True Weighted Ratio
The Incorrect Approach (Averaging Row-Level Ratios):
If the analyst writes the row-level calculation [Profit] / [Sales] and drags it onto the view as AVG([Profit Ratio]) , Tableau calculates the arithmetic mean of the two percentages: Average = 50 % + 10 % 2 = 30.0 % \text{Average} = \frac{50\% + 10\%}{2} = 30.0\% Average = 2 50% + 10% = 30.0%
The two results answer different questions. The 30.0% value is the unweighted average of transaction margins. The 10.4% value is total profit divided by total sales, which is the overall profit margin for this example. Choose the formula from the metric definition; do not label an average of row ratios as an overall margin.
The Correct Approach (Aggregate Calculation): // Overall profit divided by overall sales:
SUM([Profit]) / SUM([Sales])
Tableau first sums profit and sales at the view partition, then divides the aggregates ($1,050 / $10,100 = 10.4%). That is the appropriate calculation when the business definition is overall profit divided by overall sales; a metric defined as the mean transaction margin would intentionally use the row-level ratios instead.
Deconstructing the Error: "Cannot Mix Aggregate and Non-Aggregate Arguments"
Every Tableau developer encounters this infamous error message:
- "Cannot mix aggregate and non-aggregate arguments with the function '...'."
- Why the Error Occurs
This error arises when an expression attempts to evaluate an unaggregated, row-level field alongside an aggregate calculation within the same scalar operation. For example: // INVALID: Mixing row-level [Region] with aggregate SUM([Sales])
IF [Region] = 'West' THEN SUM([Sales]) END
- // INVALID: Mixing row-level [Sales] with aggregate AVG([Sales])
- [Sales] > AVG([Sales])
In the first formula, [Region] is evaluated for each individual row, while SUM([Sales]) is evaluated across all rows in the partition. Tableau's compiler cannot decide whether the resulting output belongs on a single row or as a summary mark for the partition.
How to Resolve the Error
Depending on business intent, analysts resolve this error using one of three proven strategies:
Strategy 1: Move the conditional logic inside the aggregation (Row-level test): // Valid: Evaluates IF row-by-row, then sums the resulting rows
- SUM(IF [Region] = 'West' THEN [Sales] END)
- Strategy 2: Aggregate the non-aggregate field using ATTR() : // Valid: Both terms are aggregated
- IF ATTR([Region]) = 'West' THEN SUM([Sales]) END
Strategy 3: Use a Level of Detail (LOD) Expression to compute the aggregate as a row-level value: // Valid: FIXED LOD expression returns a row-level scalar across all records
- [Sales] > { FIXED : AVG([Sales]) }
- Counting Aggregations: COUNT() vs. COUNTD()
Tableau provides two primary counting aggregations that differ sharply in mathematical behavior and computational overhead:
- Feature COUNT([Field]) COUNTD([Field]) (Count Distinct)
- Computation Counts all non-null rows/occurrences Counts unique, distinct non-null values
Mathematical Property Additive: ∑ ( Counts ) = Total Count \sum(\text{Counts}) = \text{Total Count} ∑ ( Counts ) = Total Count Non-Additive: Distinct counts cannot be summed
Query Performance Commonly cheaper because it counts non-null occurrences Can require more work because distinct values must be identified
Data Blending Commonly supported on secondary data sources Subject to blending restrictions for non-additive aggregates; support depends on the linking fields and fields present in the view
- Duplicate Values Every duplicate row increments the count Duplicates are deduplicated into 1 instance
- Null Handling Ignores nulls ( COUNT(NULL) is 0) Ignores nulls (null is never counted as a distinct value)
Tip
Performance Best Practice: Use COUNTD() when the question requires distinct entities, but test it on the target connection and view grain. A high-cardinality distinct count can cost more than COUNT() , and the source engine, filters, indexes, extract design, and grouping dimensions all affect the result.
The Attribute Function ( ATTR ) & Resolving the Asterisk ( * )
The Attribute ( ATTR ) function is Tableau's built-in mechanism for testing whether all rows within an aggregated group share a single, identical value.
The Mathematical Formula of ATTR()
Under the hood, Tableau evaluates ATTR([Field]) using the following exact logical formula: IF MIN([Field]) = MAX([Field]) THEN
- MIN([Field])
- ELSE
- '*'
- END
How ATTR() Evaluates:
Single Unique Value: If every record in the partition has the same value (e.g., all rows have State = 'Texas' ), then MIN('Texas') equals MAX('Texas') . Tableau successfully displays 'Texas' .
Multiple Distinct Values: If the partition contains records with different values (e.g., some rows have 'Texas' and others have 'California' ), then MIN('California') does not equal MAX('Texas') . Because Tableau cannot display multiple distinct values in a single cell or mark, it renders an asterisk ( * ) .
All Nulls: If every record in the partition is NULL , MIN() and MAX() evaluate to NULL , and Tableau displays a blank or Null . +-----------------------------------------------------------------------------------+
- | HOW ATTR() EVALUATES A PARTITION |
- +------------------------------------+--------------------------+-------------------+
- | Partition Contents | MIN() vs MAX() | Visual Output |
- +------------------------------------+--------------------------+-------------------+
- | ['Texas', 'Texas', 'Texas'] | MIN = MAX ('Texas') | 'Texas' |
- | ['California', 'Texas', 'Oregon'] | MIN != MAX | '*' (Asterisk) |
- | [NULL, NULL, NULL] | Both NULL | NULL (Blank) |
- +------------------------------------+--------------------------+-------------------+
- Common Scenarios Where the Asterisk Appears
Data Blending: When an analyst drags a secondary dimension into a worksheet, Tableau automatically aggregates it as ATTR() . If multiple secondary records link to a single primary mark, an asterisk appears.
Tooltips: If a dimension is not present on Rows, Columns, or Detail, adding it to the Tooltip shelf defaults to ATTR([Field]) . If the mark represents multiple categories, hovering over the mark displays an asterisk in the tooltip.
Aggregate Calculated Fields: When authoring formulas that compare dimensions alongside aggregated measures.
Concrete Solutions to Resolve the Asterisk ( * )
Add the Dimension to Detail: Drag the field from the secondary source or Data pane onto the Detail shelf on the Marks card. This increases the view's Level of Detail so that each mark represents a single unique value, allowing ATTR() to return the actual string instead of * .
Change the Aggregation to MIN() or MAX() : If displaying any single representative value is acceptable to business stakeholders, right-click the pill and change its aggregation from Attribute to Minimum or Maximum .
Migrate to the Modern Data Model (Relationships): Replace legacy Data Blending with Relationships in the Logical Layer. Relationships preserve each table's native level of detail and eliminate the forced ATTR() aggregation imposed by blending.