Tableau Quiz: Joins
10 questions · exam conditions
0:00
JoinsQuestion 1 of 10

An Orders table and a Returns table both contain Order ID and Order Year. Order IDs restart each calendar year, so the same Order ID can refer to different orders in different years. The current join uses only Order ID and incorrectly associates some returns with multiple orders.

Which change most directly corrects the join while retaining only genuine order-return matches?

Change to a full outer join on Order ID so unmatched yearly records remain visible.
Use an inner join with clauses for Order ID and Order Year combined with AND.
Use an inner join with clauses for Order ID and Order Year combined with OR.
Replace the Order ID clause with Order Year so all annual records are grouped together.
← Back to quizzes

Tableau Quiz

Tableau Quiz: Joins

Practice Joins in Tableau with focused quiz questions that help you check what you know, review explanations, and build confidence with test-style prompts.

What this quiz covers

This quiz focuses on Joins, giving you a quick way to practice the rules, question types, and explanations that matter most for Tableau.

How to use this quiz

Try each quiz question before looking at the correct answer. Use the explanations to review missed ideas, then come back to similar questions until the pattern feels familiar.

All questions

Question 1

An Orders table and a Returns table both contain Order ID and Order Year. Order IDs restart each calendar year, so the same Order ID can refer to different orders in different years. The current join uses only Order ID and incorrectly associates some returns with multiple orders.

Which change most directly corrects the join while retaining only genuine order-return matches?

  1. Change to a full outer join on Order ID so unmatched yearly records remain visible.
  2. Use an inner join with clauses for Order ID and Order Year combined with AND. (correct answer)
  3. Use an inner join with clauses for Order ID and Order Year combined with OR.
  4. Replace the Order ID clause with Order Year so all annual records are grouped together.
Explanation: When a join produces incorrect matches, the first thing to ask yourself is: what combination of fields truly makes a record unique? In this scenario, Order IDs reset every year, meaning Order ID alone is not a unique identifier — you need both Order ID and Order Year together to pinpoint a specific order. This is a compound key situation, and your join logic must reflect it. The correct fix is B: an inner join with both Order ID and Order Year connected by AND. This ensures a return row matches an order row only when both fields agree simultaneously — the right order, in the right year. The AND operator is critical here because both conditions must be true at once for a match to be valid. A is wrong because switching to a full outer join doesn't address the root problem — the join condition itself. A full outer join would actually make things worse by surfacing even more unmatched or incorrectly matched rows, not fewer. C is a particularly tempting trap. Using OR instead of AND means a return matches any order that shares either the same Order ID or the same Order Year — which would generate far more false matches than even the original broken join. D eliminates the Order ID entirely, which means you'd be grouping all returns with all orders from the same year regardless of which order they belong to — completely losing the specific order-level relationship. A useful rule of thumb: when a field isn't unique on its own, every join involving that field needs additional conditions connected by AND to narrow matches to truly identical records.

Question 2

Orders stores Customer ID as an integer, such as 123. Customers stores the same identifiers as text padded with leading zeros, such as 00123. Every Customers value consists only of digits. The join must correctly recognize these as the same identifier.

Which join configuration most directly creates the intended matches?

  1. Use a join calculation that converts the Customers text ID to an integer before comparison. (correct answer)
  2. Convert the Orders integer ID to text and compare it directly with the padded text ID.
  3. Use a full outer join so differently formatted identifiers are treated as matching records.
  4. Use an inner join without conversion because Tableau automatically normalizes leading zeros across data types.
Explanation: When joining tables with mismatched data types or formatting, your goal is to make the comparison happen on a common, consistent representation. The question here tests whether you understand how Tableau join calculations can bridge formatting gaps between fields. The cleanest solution is A: writing a join calculation that converts the Customers text ID to an integer. Since 00123 contains only digits, converting it to an integer naturally strips the leading zeros, producing 123 — which matches the Orders integer directly. This is a precise, targeted fix that addresses the actual mismatch. B goes in the wrong direction. Converting the Orders integer 123 to text gives you "123", which still won't match "00123" because the leading zeros remain in the Customers field. A direct text comparison would fail unless you also pad the Orders value, making this approach incomplete as described. C is a classic trap. A full outer join determines how unmatched rows are handled, not whether two values are considered equal. Changing the join type does nothing to reconcile 123 and "00123" — they'll still be treated as different values regardless of join type. D is simply false. Tableau does not automatically normalize leading zeros or cross-type formatting differences. If you attempt a naive join between mismatched types or formats, you'll get errors or incorrect results, not silent normalization. The broader takeaway: when you see a data type or formatting mismatch in a join scenario, think join calculations first. They let you apply transformations — like INT() or STR() — directly within the join condition, solving the problem at its source.

Question 3

Two warehouse systems contain partially overlapping lists of Item IDs. For reconciliation, analysts must classify each ID as present in both systems, present only in System A, or present only in System B. The System A table is placed on the left of the join.

Which join type provides the rows needed for all three classifications in one joined result?

  1. A left join, because it preserves System A records and all matched System B records.
  2. A right join, because it preserves System B records and all matched System A records.
  3. An inner join, because it retains every Item ID that can be compared across systems.
  4. A full outer join, because it retains matches and unmatched records from both systems. (correct answer)
Explanation: When reconciling two data sources, your goal is to classify every record — matched ones and unmatched ones from either side. That classification problem is your signal to reach for a specific join type before you even look at the answer choices. A full outer join returns three categories of rows in a single result: records that matched across both tables, records from the left table with no match on the right (nulls in System B columns), and records from the right table with no match on the left (nulls in System A columns). That maps perfectly to "in both," "only in A," and "only in B." D is the correct answer because it's the only join that preserves unmatched rows from both sides simultaneously. A is wrong because a left join preserves all of System A and only the matched rows from System B. Any Item ID that exists exclusively in System B is dropped entirely — you'd miss an entire classification category. B has the mirror problem: a right join keeps all of System B but drops unmatched System A records, so IDs found only in System A disappear. C is the most tempting trap if you misread "every ID that can be compared" as meaning all IDs — but an inner join returns only matched rows. Any ID missing from either system is excluded, leaving you with no way to identify the unmatched records at all. A useful rule of thumb: if the word "all" applies to both tables in the question, think full outer join. If it applies to just one side, think left or right. If it applies to neither, think inner.

Question 4

A Tableau data source physically joins Customers to Orders and then joins the result to Shipments. Some customers have no orders, and some orders have not yet shipped. Customers must remain available for analysis even when they have neither an order nor a shipment.

Assuming Customers is leftmost, which sequence of join types satisfies the requirement?

  1. Inner join Customers to Orders, then left join the result to Shipments.
  2. Left join Customers to Orders, then inner join the result to Shipments.
  3. Full outer join Customers to Orders, then inner join the result to Shipments.
  4. Left join Customers to Orders, then left join the result to Shipments. (correct answer)
Explanation: When chaining joins in Tableau, you need to think about row preservation at every step. The core question is: which join type keeps unmatched rows from the left table? A left join does exactly that — it keeps all rows from the left side and fills NULLs where the right side has no match. Here, the requirement is that every customer must survive the entire join chain, even with no orders and no shipments. A left join from Customers to Orders preserves all customers, giving NULL order columns for unordered customers. Then a second left join from that result to Shipments preserves every row already in the intermediate result — including those NULL-order customers — and simply fills NULL shipment columns where no match exists. This is option D, and it's the only sequence that keeps every customer intact through both joins. Option A fails immediately at step one: an inner join between Customers and Orders drops any customer with no orders before Shipments even enters the picture. Those customers are gone permanently. Option B correctly preserves customers in the first join, but then an inner join to Shipments discards any row where no shipment match exists — which eliminates customers whose orders haven't shipped yet, and crucially, customers with no orders at all (whose order columns are NULL and will never match a shipment). Option C uses a full outer join first, which is unnecessary and still fails for the same reason as B: the trailing inner join to Shipments purges unmatched rows. A useful rule of thumb: if a row must survive to the end, every join it passes through must be a left join (or outer). One inner join anywhere in the chain can silently erase the rows you're trying to protect.

Question 5

A Customers table contains one row each for customer IDs C1, C2, and C3. An Orders table contains two rows for C1, one row for C2, and one row for C4. You join Customers on the left to Orders on the right using Customer ID.

How many rows will a left join produce before any filters or aggregations are applied?

  1. 33 rows, because the left table contains three unique customer records.
  2. 44 rows, because matches can duplicate a left row and unmatched customers remain. (correct answer)
  3. 55 rows, because every row from both source tables is retained.
  4. 66 rows, because each customer is paired with every possible order record.
Explanation: When working with joins in Tableau, the key question to ask yourself is: how does each row in the left table match rows in the right table? A left join keeps every row from the left table, duplicating it for each matching row on the right — and preserving it as a null-padded row when no match exists. Here's the row-by-row logic for this scenario. Customer C1 matches two orders, so it produces two rows. Customer C2 matches one order, producing one row. Customer C3 matches no orders, but because this is a left join, it's still retained as one row (with nulls for order fields). That's 2+1+1=42 + 1 + 1 = 4 rows total. Note that C4 exists only in the Orders table, so it's dropped entirely — the right table's unmatched rows are discarded in a left join. Answer B is correct. Answer A is tempting but wrong — it assumes the join simply returns one row per customer, ignoring that multiple matches on the right side duplicate the left row. Answer C describes a full outer join, which retains all rows from both tables (including C4), giving five rows here. Answer D describes a cross join, which multiplies every left row by every right row — that's a completely different operation altogether. A reliable study tip: sketch a small table like this one and trace each left-table row through the join manually. On the Tableau exam, join questions almost always hinge on understanding row multiplication from one-to-many matches.

Question 6

Customers is left joined to Campaign Responses on Customer ID so that customers without responses are retained. After the join, a data source filter keeps only rows where Response Status equals Active. A customer can have multiple active response records.

What is the resulting effect of the filter on customers and row counts?

  1. All customers remain, and null Response Status fields are populated with Active by the filter.
  2. Only customers with at least one active response row remain, and they may appear more than once. (correct answer)
  3. Customers with inactive responses remain, but customers with no response records are removed.
  4. Each customer appears exactly once because the left join guarantees one output row per customer.
Explanation: Whenever you see a question combining a left join with a post-join filter, you need to think in two separate stages: what the join produces first, and then what the filter removes afterward. The left join starts by preserving every customer row, even those with no matching Campaign Response record — those unmatched customers receive NULL for all response fields, including Response Status. So far, so good for unmatched customers. But then the data source filter steps in and keeps only rows where Response Status equals Active. NULL does not equal Active, so any customer row carrying a NULL Response Status is eliminated. Customers with at least one active response survive, and because a customer can have multiple active response records, that same customer can appear in multiple rows — one per active response. That makes B the correct answer. A is wrong because filters never populate or fill in data — they only include or exclude existing rows. A NULL value stays NULL; the filter simply drops it rather than replacing it with Active. C is wrong because customers with inactive responses also fail the filter condition (their Response Status is not Active), so they are removed just like customers with no responses at all. D is wrong on two counts: a left join does not limit output to one row per customer when multiple matches exist on the right side, and the filter further changes which rows survive anyway. The study tip to remember: a filter applied after a left join effectively converts it into something closer to an inner join for unmatched rows — always trace the data flow stage by stage before drawing conclusions.

Question 7

A Tableau data source joins an Agents table on the left to a Tickets table on the right using Agent ID. Some tickets are unassigned and therefore have a null Agent ID. Some agents have never handled a ticket.

You need every ticket in the result, including unassigned tickets, but you do not want rows for agents who have never handled a ticket. Which join type should you use?

  1. Use a left join so every agent is retained and matching ticket data is added.
  2. Use an inner join so only tickets with a matching agent record are retained.
  3. Use a right join so every ticket is retained and matching agent data is added. (correct answer)
  4. Use a full outer join so every ticket and every agent record is retained.
Explanation: When working with joins in Tableau, the key question to ask yourself is: which table's rows must I preserve completely? The answer to that question tells you which side of the join should be "outer" — meaning all its rows are kept regardless of whether a match exists on the other side. Here, the requirement is clear: every ticket must appear, including unassigned ones with a null Agent ID. The Tickets table sits on the right side of the join. To guarantee every row from the right table is retained — matched or not — you need a right join. Tableau will fill in nulls for any Agent columns where no match exists, which is exactly the behavior you want for unassigned tickets. That makes C the correct answer. A is wrong because a left join preserves every row from the left table — Agents, in this setup. That would keep agents who've never handled a ticket (exactly what you're told to exclude) and would drop unassigned tickets entirely. B describes an inner join, which only returns rows where Agent ID matches on both sides. Unassigned tickets have a null Agent ID, so they'd be silently dropped — violating the core requirement. D, a full outer join, returns every agent and every ticket. That sounds generous, but it also reintroduces agents who have never handled a ticket, which the question explicitly forbids. A handy tip: map the tables to "left" and "right" positions first, then match the requirement ("keep everything from  ") to the join type — left, right, inner, or full outer.

Question 8

A Departments table contains one row per department with an annual budget. An Employees table contains multiple rows per department. Analysts physically join Departments to Employees on Department ID and then sum Annual Budget across the joined rows.

Which statement correctly describes whether selecting a different join type can prevent budget duplication while retaining employee-level detail?

  1. An inner join prevents duplication because it retains only departments having matching employees.
  2. A left join prevents duplication because each department originates as one row on the left.
  3. No join type alone prevents duplication; the one-to-many match repeats each department budget. (correct answer)
  4. A full outer join prevents duplication because it preserves unmatched rows from both tables.
Explanation: Whenever you see a question about joining tables with different cardinalities — meaning one table has one row where the other has many — your first instinct should be to think about what happens to values on the "one" side of that relationship. Here's the core issue: when you join a Departments table (one row per department) to an Employees table (many rows per department), every employee record pulls in the full department row, including its Annual Budget. If a department has 10 employees, that budget figure appears 10 times in the joined result. Summing it produces a value 10× too large. This is data duplication caused by the one-to-many relationship itself — and it happens regardless of join type. Inner, left, right, full outer — none of them change the fundamental matching logic that repeats the department row for each employee match. That makes C correct. A is wrong because an inner join only filters out unmatched rows — it does nothing to prevent a matched department budget from repeating once per employee. B is a tempting trap: a left join does originate each department as one row before the join, but after matching, that single row fans out into multiple rows (one per employee), duplicating the budget just as badly. D is wrong because a full outer join adds even more rows by preserving unmatched records from both sides — it moves further from preventing duplication, not closer. The study tip here: join type controls which rows are included, not how many times a value repeats. Preventing fan-out duplication requires a modeling fix — such as aggregating before joining or using a data model relationship instead of a physical join.

Question 9

Table L contains key A twice, key B once, and one null key. Table R contains key A three times, key C once, and one null key. Tableau performs a full outer join using an equality condition on the key. Under standard null comparison behavior, null keys do not match each other.

How many rows will the joined result contain?

  1. 88 rows, because the two A keys in L each match one combined A record from R.
  2. 99 rows, because the two null-key records match each other under equality.
  3. 1010 rows, because the many-to-many A matches produce 6 rows and the four unmatched records add one row each. (correct answer)
  4. 1111 rows, because each source row from both tables is counted individually after matched rows are produced.
Explanation: When working with join operations in Tableau, always break the problem into two parts: matched rows (from the join condition) and unmatched rows (from the outer join padding). Start with the many-to-many A matches. Table L has 2 rows with key A, and Table R has 3 rows with key A. Every L row pairs with every R row, producing 2×3=62 \times 3 = 6 matched rows. Next, identify the unmatched records. Table L has key B (no match in R) and one null key (nulls don't match under equality) — that's 2 unmatched L rows, each padded with nulls from R. Table R has key C (no match in L) and one null key — that's 2 unmatched R rows, each padded with nulls from L. The total is 6+2+2=106 + 2 + 2 = 10 rows, confirming C is correct. Choice A is wrong because it collapses R's three A rows into one, treating a many-to-many relationship as if it were a lookup. Choice B introduces a false assumption — under standard SQL equality semantics, NULL = NULL evaluates to unknown, not true, so null keys never match each other. Those two null rows remain unmatched and appear separately. Choice D arrives at 11 by double-counting: once you've accounted for matched pairs and unmatched stragglers correctly, there's no additional row to add. As a strategy tip: always sketch a small table when you see join questions. Count matched combinations using multiplication, then add each orphaned row from both sides individually — this two-step method prevents the overcounting and undercounting traps that make wrong answers tempting.

Question 10

A data source currently joins Customers on the left to Orders on the right using a left join on Customer ID. You must reverse the positions of the tables on the Tableau join canvas without changing which records are preserved.

After placing Orders on the left and Customers on the right, which join type produces the equivalent retained rows?

  1. A right join, preserving every customer and adding any matching order records. (correct answer)
  2. A left join, preserving every order and adding any matching customer records.
  3. An inner join, preserving customers only when at least one matching order exists.
  4. A full outer join, preserving unmatched customers and unmatched orders equally.
Explanation: When working with Tableau joins, the key insight is that a join type defines which side's unmatched rows are preserved — and that designation is always relative to position (left vs. right). So when you swap table positions, you must also swap the join direction to keep the same records. Originally, Customers is on the left with a left join, meaning every customer row is preserved regardless of whether a matching order exists. When you flip the tables — Orders on the left, Customers on the right — Customers is now the right-side table. To still preserve every customer row, you need a right join, which keeps all rows from the right table and adds matching rows from the left. That's exactly what answer A describes, making it correct. Answer B is tempting but wrong: a left join after the swap would preserve every order row, not every customer — the opposite of the original intent. Answer C describes an inner join, which only retains rows where both a customer and an order match, discarding unmatched customers entirely. Answer D suggests a full outer join, which preserves unmatched rows from both sides — this over-includes data and produces a different result set than the original left join. A reliable strategy here: mentally track which table you want to preserve all rows from, then match that to the correct join type based on position. If your "must-keep" table is on the left, use a left join; if it's on the right, use a right join. Swapping table positions always requires swapping left↔right join direction to maintain equivalent output.