Berserk Docs
Tabular OperatorsOther Operators

union

Combines rows from multiple sources — real tables, inline `datatable(...)` literals, or pipeline subqueries — into a single result set.

Combines rows from multiple sources — real tables, inline datatable(...) literals, or pipeline subqueries — into a single result set. Schemas combine column-wise (outer-union by default): every column from every source appears, and rows that lack a column read it as null.

Where it can appear

union works in both leading position (start of a query) and pipeline position (after |):

union T1, T2, ...                 // leading
T1 | union T2, T3                 // pipeline (LHS counts as the first source)
T1 | summarize ... | union (datatable(...))   // pipeline with non-scan LHS

Source kinds

An argument can be a real table name, a parenthesised subquery, or an inline datatable(...) literal. Mixing kinds within one union is supported.

withsource provenance

When withsource = Col is set, each row gets a string Col identifying its source:

  • Real table → the table name (e.g. default).
  • Inline datatable(...)union_arg<N>, where <N> is the source's 0-indexed position in the user's argument list.
  • Pipeline subqueryunion_arg<N> (treated as a synthetic source).

Restrictions

  • Mixed real-table + inline-datatable unions require a timestamp:datetime column on every inline datatable. Without it, the query's time-range filter would silently drop those inline rows. Berserk rejects this at bind time with a clear error.
  • Pipeline-position with a real-table RHS (e.g. T | summarize ... | union T2) parses and binds, but execution is not yet implemented — it needs join-style filter push-down to avoid pulling full table scans to the coordinator. Mix with inline datatables only runs end-to-end today.

Differs from Microsoft KQL

Berserk matches ADX byte-for-byte for all single-level union shapes: source-name numbering follows user-source order, real tables resolve withsource to the table name, inline datatables resolve to union_arg<N>, and schema merging is the column-wise superset.

Chained pipeline withsource differs. When a pipeline-position union nests inside another (e.g. union T, (datatable(...)) | union withsource=src (datatable(...))), Berserk preserves the inner sources' identities (T, union_arg1, union_arg2). ADX collapses the entire LHS pipeline to a single opaque union_arg0. Berserk's behaviour is richer and avoids losing inner provenance, but is not strictly wire-compatible with ADX in this case. For ADX-portable queries that depend on withsource, write the union as a single leading-position list rather than chaining.

Syntax

union T1, T2, ...

Combine rows from multiple tables (outer join of schemas)

Parameters

NameDescription
tablesTwo or more table names, parenthesised subqueries, or datatable(...) literals

Syntax

union kind=inner T1, T2, ...

Combine rows, keeping only columns common to all tables

Parameters

NameDescription
tablesTwo or more table names, parenthesised subqueries, or datatable(...) literals

Syntax

union withsource=col T1, T2, ...

Combine rows with a column identifying the source for each row

Parameters

NameDescription
colName for the source column (table name for real tables, union_arg<N> for synthetic sources)
tablesTwo or more table names, parenthesised subqueries, or datatable(...) literals

Syntax

T1 | union T2, T3

Pipeline-position — LHS is treated as the first source

Parameters

NameDescription
tablesOne or more table names, parenthesised subqueries, or datatable(...) literals

Examples

Example 1 — Combine two warrior rosters

union (datatable(warrior:string, weapon:string)[
  "Ragnar", "axe",
  "Bjorn", "sword"
]), (datatable(warrior:string, weapon:string)[
  "Harald", "spear",
  "Rollo", "axe"
])
warrior (string)weapon (string)
Bjornsword
Haraldspear
Ragnaraxe
Rolloaxe

Example 2 — With withsource, inline datatables get union_arg<N> provenance

union withsource = src (datatable(x:long)[
  1,
  2
]), (datatable(x:long)[
  3
])
src (string)x (long)
union_arg01
union_arg02
union_arg13

On this page