Edilitics | Data to Decisions

Pivot / Unpivot

Pivot reshapes long to wide: category values become headers. Unpivot reshapes wide to long: columns stack into key-value rows. Configure aggregations visually.

Pivot / Unpivot reshapes your dataset between long and wide formats. Pivot takes unique values from a categorical column and turns each one into its own column header, filling cells with values from a numerical column. Unpivot does the reverse - it stacks selected columns into key-value row pairs, increasing row count while reducing column count. Both subtypes are in one operation, toggled by a tab selector.


When to Use

Use Pivot when:

  • Converting monthly sales rows into month columns for a side-by-side report.
  • Building a crosstab of revenue by region and product tier.
  • Preparing data for a spreadsheet that expects one column per category value.

Use Unpivot when:

  • Converting a wide spreadsheet (one column per year) into a long format for BI tools.
  • Stacking revenue, cost, and profit columns into a single metric column with a value column.
  • Normalizing data before joining with a long-format reference table.

Sample Dataset

The examples in this doc use the Edilitics sample orders dataset. Download it to follow along in your own workspace.

edilitics_sample_orders.csv

Sample orders dataset for hands-on practice · 500 rows

Download

Relevant columns:

Prop

Type


How to Apply Pivot / Unpivot

Open the Pivot / Unpivot operation

In your Transform pipeline, click Add Operation and select Pivot / Unpivot from the operation list.

Select the subtype

Click Pivot (Long to Wide) or Unpivot (Wide to Long) to switch between modes. The fields below update for the selected subtype.

Configure the fields

Follow the configuration for the selected subtype. See the Pivot and Unpivot sections below.

Click Save & Preview

Click Save & Preview. The dataset is reshaped. The success toast confirms:

  • Pivot: "Pivot applied. Table reshaped to wide format."
  • Unpivot: "Unpivot applied. Table reshaped to long format."

Verify in the preview

Pivot: check that each unique value from the Column Field is now a column header. Unpivot: check that row count equals original rows multiplied by the number of Value Columns selected.


Pivot (Long to Wide)

Pivot creates one column per unique value in the Column Field, fills cells with values from the Value Field, and aggregates when multiple rows share the same Index Column value and Column Field value.

Fields:

FieldRequiredAccepted column typesDescription
Index ColumnYesAll typesColumn whose unique values become the row keys in the output. One row per unique value.
Column FieldYesCategorical (string) onlyColumn whose unique values become the new column headers.
Value FieldYesNumerical onlyColumn whose values fill the new columns.
Aggregate FunctionNo-How to handle multiple values for the same index + column combination. Default: First.

Aggregate functions:

LabelBehaviour
FirstTakes the first value encountered for each index + column combination.
SumSums all values for each combination.
MeanAverages all values for each combination.
MinTakes the minimum value for each combination.
MaxTakes the maximum value for each combination.
CountCounts the number of rows for each combination.

Preview output columns button:

Once Index Column, Column Field, and Value Field are all selected, a Preview output columns button appears. Click it to see how many new columns will be created and the first 5 column names before saving.

Pivot creates one new column per unique value in the Column Field. If that column has high cardinality (hundreds or thousands of unique values), the output will have hundreds or thousands of columns. Check cardinality before pivoting to avoid performance issues.


Unpivot (Wide to Long)

Unpivot stacks selected columns into rows, producing a key column (variable name) and a value column. Row count equals original rows multiplied by the number of Value Columns selected.

Fields:

FieldRequiredAccepted column typesDescription
Index Columns (keep as-is)YesAll typesOne or more columns to keep unchanged as row identifiers. Multi-select.
Value Columns (stack into rows)YesAll types except index columnsOne or more columns to collapse into rows. Each selected column becomes a row per original row. Multi-select.
Variable column nameNo-Name for the new column that stores the original column name. Default: variable.
Value column nameNo-Name for the new column that stores the cell values. Default: value.

Live row count preview:

When Index Columns and Value Columns are both selected, a preview message appears: "Will produce N x rows per input row, with columns: [index columns], [variable name], [value name]."


Before and After

Pivot example

Index Column: region. Column Field: product_tier. Value Field: revenue. Aggregate: Sum.

Input (long format, 500 rows):

regionproduct_tierrevenue
North AmericaEnterprise12450.00
North AmericaStarter3200.00
EuropeGrowth8320.50
EuropeEnterprise15100.00
.........

Output (wide format, 5 rows - one per region):

regionEnterpriseGrowthStarter
North America421300.00189400.0010730.00
Europe284100.00192000.00108110.75
Asia Pacific198400.00167200.00147290.25
Latin America134100.0098200.00166440.00
Middle East & Africa99100.0087200.00126350.00

Row count reduced from 500 to 5. Three new columns from the 3 unique product_tier values.


Unpivot example

Index Columns: region. Value Columns: Enterprise, Growth, Starter. Variable column name: tier. Value column name: revenue.

Input (wide format, 5 rows):

regionEnterpriseGrowthStarter
North America421300.00189400.0010730.00
Europe284100.00192000.00108110.75

Output (long format, 15 rows - 5 x 3 columns):

regiontierrevenue
North AmericaEnterprise421300.00
North AmericaGrowth189400.00
North AmericaStarter10730.00
EuropeEnterprise284100.00
EuropeGrowth192000.00
EuropeStarter108110.75
.........

Row count multiplied by 3 (number of Value Columns). Two new columns: tier and revenue.


Code Equivalent

-- Pivot (PostgreSQL crosstab)
SELECT
  region,
  SUM(CASE WHEN product_tier = 'Enterprise' THEN revenue END) AS "Enterprise",
  SUM(CASE WHEN product_tier = 'Growth' THEN revenue END) AS "Growth",
  SUM(CASE WHEN product_tier = 'Starter' THEN revenue END) AS "Starter"
FROM orders
GROUP BY region;

-- Unpivot (PostgreSQL UNNEST)
SELECT region, tier, revenue
FROM orders
CROSS JOIN LATERAL (
  VALUES ('Enterprise', enterprise), ('Growth', growth), ('Starter', starter)
) AS t(tier, revenue);
import polars as pl

# Pivot: region rows, product_tier columns, sum of revenue
df_wide = df.pivot(
    values="revenue",
    index="region",
    columns="product_tier",
    aggregate_function="sum"
)

# Unpivot: stack Enterprise, Growth, Starter into rows
df_long = df_wide.melt(
    id_vars=["region"],
    value_vars=["Enterprise", "Growth", "Starter"],
    variable_name="tier",
    value_name="revenue"
)

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.


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

Pivot:

Prop

Type

Unpivot:

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