← All posts
by Arif Aslam 4 min read

Adding a Calculated Column to Your CSV

Your orders.csv has unit_price and quantity, but no line total. Your shipping manifest has a per-unit weight and a count, but nothing that says how heavy each shipment is. Your HR export has first_name and last_name but no full_name.

The data you need is there. It's just not in its own column yet.

In Excel, you'd write a formula in a new column and drag it down. In SQL, you'd add an expression to your SELECT. In ExploreMyData, you type the formula once and the computed column lands next to the originals.

Multiplying two columns: order totals

The most common case. You have unit_price and quantity, and you want a line_total column.

Click the green + in the Pipeline panel and select Math from the Transform group. Math is one free-text formula box. There are no operand pickers, no column dropdowns and no operator buttons: you type the whole expression, with column names in double quotes.

"unit_price" * "quantity"

Below the box sits Apply results into. Choose New Column and name it line_total, or choose Existing Column to overwrite a column you already have. Leave the new-column name blank and you get one called result.

ExploreMyData generates:

SELECT *, "unit_price" * "quantity" AS "line_total" FROM "orders"

Every row now has a computed total. The column shows up in your table just like the original columns, and you can sort, filter, or aggregate on it.

order_id product unit_price quantity line_total
1001Wireless Mouse29.99389.97
1002USB-C Hub49.99149.99
1003Laptop Stand34.99269.98
1004Keyboard79.994319.96

New column line_total computed as "unit_price" * "quantity" for every row.

The same trick on a different unit: shipment weight

The shipping manifest for those same orders has a unit_weight_kg column and the same quantity. The carrier wants one number per shipment.

Open Math again and type:

"unit_weight_kg" * "quantity"

Apply the result into a new column called shipment_weight_kg. That's the whole step. Anything you add below it in the pipeline can now use that column.

Using Add Column for custom expressions

Math handles arithmetic. When you want a DuckDB function rather than an operator, reach for Add Column from the Columns group. It gives you a "New column name" field, a free-text expression box, and an optional output type: text, numeric or date.

Carriers bill on whichever is heavier, actual weight or volumetric weight. With the carton dimensions in the same file, that comparison is a single expression:

GREATEST("shipment_weight_kg", ROUND("length_cm" * "width_cm" * "height_cm" / 5000.0, 2))

Name it billable_weight_kg and set the type to numeric. ExploreMyData wraps the expression in TRY_CAST(... AS DOUBLE), so a row with a junk dimension comes back empty rather than failing the step.

Or guard a division that might land on a zero:

ROUND("shipping_cost" / NULLIF("billable_weight_kg", 0), 2)

Add Column is the escape hatch. Anything DuckDB supports as a column expression, you can use here.

order_id unit_weight_kg quantity shipment_weight_kg volumetric_weight_kg billable_weight_kg
10010.1230.360.290.36
10020.0910.090.120.12
10031.2522.502.402.50
10040.8543.405.005.00

Same four orders, same quantities. shipment_weight_kg is the Math step "unit_weight_kg" * "quantity". volumetric_weight_kg comes from the carton dimensions divided by 5000, and billable_weight_kg is the GREATEST of the two. Orders 1002 and 1004 are light and bulky, so volume wins.

Combining text columns

Not all calculated columns involve numbers. You might need to combine first_name and last_name into a full name.

Use Combine Columns from the Columns group. It has one control, a chip input labelled "Define values or columns to combine". Drop in a first_name chip, type a single space and press Enter for a literal chip, then add last_name. There is no separator field: the space is a chip like any other, which is what lets you build "Last, First" or slot a middle initial in later. Apply the result into a new column called full_name.

The SQL:

CONCAT(COALESCE(CAST("first_name" AS VARCHAR), ''), ' ', COALESCE(CAST("last_name" AS VARCHAR), '')) AS "full_name"

Every column chip gets its own COALESCE, so a missing last name gives you "Jane " rather than NULL. Add a Text Transform step with "trim" on the new column to clean up the leftover space.

When types don't match

A common gotcha: your "unit_price" column was imported as text because the values had dollar signs or commas. Trying to multiply a VARCHAR by a number fails.

Fix it with Convert Type from the Transform group. "Convert to" offers exactly three options: text, numeric and date. Pick numeric and the step casts with TRY_CAST, so a value that can't convert becomes NULL instead of taking the whole operation down with it.

You don't need a Find & Replace pass first. Converting text to numeric strips commas, currency symbols ($, €, £, ₹), stray spaces and percent signs on its own, and reads (500) as -500. A cell reading $1,234.56 lands as 1234.56 in one step.

Chaining calculations

Because every operation is a pipeline step, each one sees the columns created above it. Compute shipment_weight_kg first. Then billable_weight_kg, which reads it. Then a shipping_cost_per_kg that divides by the billable figure. Every step stays small enough to read on its own.

Order matters, and steps can't be dragged around after the fact, so build them in the sequence the math needs. Delete a step in the middle and everything below it re-runs against the new input, which is how you find out quickly that a later step was leaning on a column you just removed.

Start adding columns to your data →

AA

Arif Aslam

Staff engineer in Bangalore. By day at Mammoth Analytics; building ExploreMyData on the side. More on my author page or LinkedIn.

Try it yourself

No sign-up, no upload, no tracking.

Open ExploreMyData