Skip to content

The Multi-Table Join step joins many tables (up to 32) in a single operation using a visual join-graph designer, replacing the pattern of chaining several two-table join steps. You add tables, draw joins between their columns, choose a join type and conditions per join, and map the output columns. The editor has three tabs: Tables & Joins, Output Columns, and Post-Join Filter.

For a full walkthrough, see the Multi-Table Join step guide.

orderscustomersitemsregionsone stepjoined resultup to 32 tables
Draw the joins between source tables as a graph — up to 32 tables — and the whole graph resolves to one result table in a single step, instead of chaining many two-table joins.
  • Add Table — place a source table on the canvas as a card of columns. Each table has an alias (used as alias.column) that must start with a letter or underscore and can’t be a SQL keyword.
  • Target Table — the table the joined result is written to; created if it does not exist.
  • Dynamic — give a source or the target as a reference instead of picking it: a table name, a project path (/03 Results/FACT_GL), or either carrying {variable} tokens resolved at run time. A dynamic source’s columns can’t be read at design time, so they are entered by hand in the side panel.
  • Draw joins — drag from a column dot on one table to a column on another to create a join; an optional Label names the edge.
  • Inbound Filter — a per-table filter applied before the join.
  • Re-fetch from server — refresh a table card’s columns from the latest catalog.
  • Tidy Layout / Fit to View — auto-arrange the graph, or zoom to fit; pan and zoom are also manual.
  • Undo / Redo / History — step through, review, and restore edits.
  • Filter columns… — narrow the columns shown on a table card.
  • Export — download the join diagram as an SVG.
Type Keeps
INNER Rows that match across the joined tables.
LEFT All rows from the left table, matched rows from the right.
FULL All rows from both tables.
CROSS Every combination of rows (no conditions allowed).

Each non-cross join has one or more conditions combined with AND / OR, using the operators =, <>, <, <=, >, >=, BETWEEN, IS NULL, IS NOT NULL, IN, NOT IN, LIKE, NOT LIKE.

A condition can name a column whose name has spaces or punctuation, such as Build Plant or Cust (Id); the column must exist in that input. Names containing a double quote, backtick, backslash or control character are refused.

For BETWEEN, a bound written as an input’s alias, a dot, and a column (cust.Max Id) is read as a column of that input. Any other bound is literal text, including a bare alias name with no dot. A text bound that starts with an alias and a dot, such as cust.2024 when an input has the alias cust, is therefore read as a column and reported as missing.

On the Output Columns tab, map the result columns; rename, set data type, and aggregate as needed. Same-named columns are auto-prefixed with their source alias to avoid collisions.

Each row takes its value from exactly one of three fields — setting more than one, or none, is rejected:

Kind Fields
Source column Source Alias (the owning canvas alias) plus Source (alias.column). Both required.
Constant Constant — the same fixed value on every row.
Expression Expression — a SQLAlchemy expression that may reference any canvas alias as alias.column.
  • Pick from canvas… — check off columns from every source on the canvas.
  • Add all source columns — append every column from every source.
  • Add expression column — append an expression row and open the expression editor.

The Post-Join Filter tab applies an optional filter to the joined result (a SQL HAVING equivalent) before it’s written, edited in the same expression editor. It references output columns as result.column_name; source aliases are out of scope there.

Select Also carry columns named at run time to pass through, unchanged, every source column the step doesn’t list, as the table has them when the step runs. Use it when an earlier step creates columns whose names depend on the data, such as a pivot, so you can’t list them when you build the step. Leave it off to write only the columns you list.

  • The join graph is a tree: each table joins into the result through exactly one edge (no cycles), and a table can’t join to itself.
  • The configuration is validated both when you save the step and when it runs; errors mark the offending table or join with a ⚠ marker, a failed save switches to the tab holding the first problem, and Jump to issue navigates there on demand. Output-column expressions and the Post-Join Filter are checked on save; a join that carries columns named at run time skips the expression check at save and is checked when the step runs.