Edilitics | Data to Decisions

Concat

Concatenate tables vertically, horizontally, or diagonally. Schema compatibility is checked automatically with built-in duplicate handling. No code needed.

Concat merges the current dataset with one other table from any connected integration. Three modes: Vertical stacks rows (union), Horizontal joins columns on the names the two tables share, Diagonal stacks rows while keeping every column from both tables. Always exactly two tables -- to combine three or more, chain multiple Concat steps one after another, using the result of each as the input to the next. Duplicate handling is configurable before saving.

The source table can come from a different database or integration than the current pipeline source. No need to land both datasets in a shared warehouse first.


When to Use Concat

  • Stack regional tables. Vertical concat orders_na and orders_eu into a single orders dataset for global reporting.
  • Combine attribute tables. Horizontal concat a transaction table with a metadata table that shares a key column such as order_id, joining on that shared name.
  • Append new data. Vertical concat last month's orders into the current dataset to extend the time range.
  • Keep every column from two overlapping-but-different sources. Diagonal concat two tables with mostly the same schema but a few extra columns on each side, filling the gaps with null instead of dropping columns.

Sample Dataset

The examples in this doc use three sample datasets. Download all three to follow along in your own workspace.

edilitics_sample_orders.csv

Primary orders dataset (H1) - use as the current pipeline source for vertical concat · 500 rows

Download

edilitics_sample_orders_h2.csv

Orders dataset (H2) - use as the second table for vertical concat · 250 rows

Download

edilitics_sample_products.csv

Product catalog - use as the second table for horizontal concat on product_id · 4 rows

Download

Concat Types

TypeWhat it doesRequirement
VerticalStacks rows from the selected table below the current dataset. Keeps only the columns both tables share. A dtype difference on a shared column widens automatically unless Strict is on.At least one shared column name
HorizontalJoins columns from the selected table onto the current dataset using every column name the two tables share as the join key -- not row position.At least one shared column name
DiagonalStacks rows like Vertical, but keeps every column from both tables -- a column missing from one side is null-filled rather than dropped.None -- works even with no columns in common

How to Apply Concat

Open the Concat operation

In your Transform pipeline, click Add Operation and select Concat from the operation list.

Select a concat type

In the type dropdown, choose one of:

  • Vertical - Stack rows, keeping only the columns both tables share.
  • Horizontal - Join columns on the names the two tables share.
  • Diagonal - Stack rows, keeping every column from both tables (null-filled where one side is missing a column).

The four-column header row updates for the selected type.

Select the Database

In the Database dropdown, select any connected integration. This can be the same integration as the current source or a different one.

Select the Table Name

In the Table Name dropdown, select the table to combine with. Tables already in use by previous Concat or Join operations in this pipeline are excluded.

Selecting a table triggers an automatic schema check in the background.

Review the schema check

  • Vertical / Diagonal: an informational panel lists columns found on only one side and any shared column with a different data type. For Vertical this is just informational (those columns are dropped automatically, non-shared dtypes widen); for Diagonal it never blocks the concat since missing/mismatched columns are null-filled or widened by design.
  • Horizontal: at least one shared column name is required. Once found, a Join Type field appears, choose one of Left, Right, Inner, or Full before continuing. If the two tables share no column name at all, Horizontal shows "No shared columns" and cannot proceed, use Vertical or Diagonal instead, or Join if you only want matching rows on a key you pick yourself.

Select Manage Duplicates

Choose how to handle rows that are fully identical across every column, after the two tables are combined:

  • Keep All - Keep all rows including duplicates.
  • Keep First - Keep the first occurrence of each duplicate.
  • Keep Last - Keep the last occurrence of each duplicate.
  • Drop All - Remove all rows that appear more than once.

Click Save & Preview

Click Save & Preview to merge the datasets. The success toast confirms: "Datasets merged. Preview updated with the concatenated output."


Schema Differences

Vertical and Diagonal

Vertical keeps only the columns the two tables share by name; any column present on just one side is dropped. A shared column with a different data type widens automatically (for example integer and float become float) -- this never blocks the concat unless you turn on Strict mode, which requires the two tables' schemas to match exactly and fails with a clear error on any mismatch instead.

Diagonal keeps every column from both tables. A column missing from one side is filled with null in that table's rows. A shared column with a different data type always widens automatically, Diagonal has no Strict option.

Use Vertical when you only want the columns both tables have in common. Use Diagonal when you want to keep every column, even the ones that only exist on one side.

Horizontal

Horizontal joins the two tables on every column name they have in common, not by row position. At least one shared column is required. The Join Type you pick determines which rows survive:

IssueEffectResolution
Join TypeRows kept
--------------------------------------------------------------------------------
LeftEvery row from the current dataset. Unmatched columns from the other table are null.
RightEvery row from the other table. Unmatched columns from the current dataset are null.
InnerOnly rows where the shared column(s) match in both tables.
FullEvery row from both tables, filling gaps with null where a side has no match.

This is a join on the shared column names, not a positional "paste columns side by side" operation. Row order and row count do not need to match between the two tables.


Before and After

Vertical concat

Concat edilitics_sample_orders (500 rows, 13 columns) with edilitics_sample_orders_h2 (250 rows, 15 columns) on Vertical. H2 has two extra columns (return_flag, delivery_partner) not present in H1 -- these are dropped automatically since Vertical keeps only shared columns. Manage Duplicates: Keep All.

Input (current dataset): 500 rows, 13 columns (order_id, customer_name, email, sales_rep, region, product_id, order_date, delivery_date, revenue, units_sold, discount_pct, product_tier, metadata, notes)

Second table: 250 rows, 15 columns (same 13 + return_flag, delivery_partner)

Output: 750 rows, 13 columns (return_flag and delivery_partner dropped)


Horizontal concat

Concat edilitics_sample_orders (500 rows) with edilitics_sample_products (4 rows) on product_id, Join Type Left: every order row is kept, product columns are filled in where product_id matches, and left null where it doesn't.

Output: 500 rows, 13 + 6 columns (13 from orders, 6 new from products, product_id shared)


Code Equivalent

-- Vertical concat (PostgreSQL / BigQuery / Snowflake / DuckDB)
SELECT * FROM orders_q1
UNION ALL
SELECT * FROM orders_q2;

-- Vertical concat with deduplication (keep first)
SELECT DISTINCT ON (order_id) *
FROM (
  SELECT * FROM orders_q1
  UNION ALL
  SELECT * FROM orders_q2
) combined
ORDER BY order_id;

-- Horizontal concat (join on a shared column)
SELECT a.*, b.category, b.supplier
FROM orders a
LEFT JOIN products b ON a.product_id = b.product_id;
import polars as pl

# Vertical: keep only shared columns, widen dtype mismatches safely
df_combined = pl.concat([df_q1, df_q2], how="vertical_relaxed")

# Vertical, strict: exact schema match required, errors otherwise
df_combined = pl.concat([df_q1, df_q2], how="vertical")

# Deduplicate after concat
df_combined = df_combined.unique(keep="first")

# Horizontal: join on every shared column name, Left/Right/Inner/Full
df_wide = pl.concat([df_orders, df_products], how="align_left")

# Diagonal: stack rows, union columns, widen/null-fill mismatches
df_diag = pl.concat([df_a, df_b], how="diagonal_relaxed")

After Save & Preview, the pipeline shows a DQ delta badge on this step - green if the table score improved, red if it dropped. See Data Quality Scoring for how scores are calculated.


Operation Reference

Prop

Type


Frequently Asked Questions


Next Steps

Need help? Email support@edilitics.com with your workspace, job ID, and context. We reply within one business day.

Last updated on

On this page