Files
datacontroller.io/content/feed/columns-that-are-not-in-the-table/index.md
T
dc bc27894b38 feed(derived-variables): a column that is not in the table, and why filtering needed a view
A short, opinionated post for the feed: the request that always sounds like five
minutes, the marking that says a column is computed rather than locked, and the
DATA step view that makes a derived column filterable.  Links to the docs page
and to a discovery call.

Screenshots are from a real SAS backend, so the grid shown is the shipped one -
fx badge, tinted cells, and the edge that opens the computed block.
2026-10-27 23:53:13 +00:00

5.0 KiB

title, description, date, author, authorLink, tags, previewImg
title description date author authorLink tags previewImg
The column that is not in the table Derived variables give the EDIT screen columns that do not exist in the table - computed on every read, never stored, and filterable like any other column. 2026-10-27 09:00:00 Data Controller https://www.linkedin.com/showcase/data-controller-for-sas
Announcements
Features
./derived-fx.png

The column that is not in the table

Every reporting team has a version of this request, and it always sounds like a five minute job: "can we have a region column? It is just the state, mapped. And a line value - quantity times price. We do not need it stored, we just need it on the screen."

It is never a five minute job. The column does not exist, so either the table grows a column it does not need, or the load grows a step that writes values nobody asked to keep. Either way a developer, a release and a change request are now attached to a column that is only ever looked at.

Data Controller now does the obvious thing instead. You write the expression, and the EDIT screen shows the column.

This ships with the next Data Controller release.

What it looks like

REGION is derived from STATE. LINE_VALUE is QTY * PRICE. REGION_LABEL is built on top of REGION. None of the three is a column of the table, and all three appear after the physical ones.

Nothing is stored. The values are computed every time the table is read, so they always reflect the current data and the current definition - and nothing derived is written back when a change is submitted or approved.

Marked as computed, not merely locked

A computed column cannot be edited, which raises a fair question from anyone staring at a grid: is this column locked, or is there simply nothing to edit?

So the computed ones are styled apart from ordinary read-only columns - a tinted header with an fx marker, italic tinted cells, and a left edge where the computed block begins. Hover a header and the tooltip tells you the variable's label, or its name and expression where no label was configured. Read-only by rule still looks dimmed; computed reads as computed.

And yes - you can filter on it

This is the part that took the thinking. The filter is a WHERE clause, a WHERE clause applies to the data set named on the SET statement, and a variable created in the same data step is not on that input. So the derivations are built into a DATA step view, and the filter is applied by the step that reads it - which is what makes a derived column behave like a stored one, filter bar and all:

Filters that reference a derived column are stored and re-applied exactly like any other filter, and the list of values is built from the table under the rest of the filter, as usual.

Configured in the tool, approved like everything else

Derived variables are maintained per table in the MPE_DERIVED control table - which is itself a Data Controller table, so adding one goes through the same edit, review and approve workflow as any other data change. Name, dependencies, type, length, optional format and label, and a single SAS expression; no sequence number to maintain, because the statements are generated in dependency order.

A bad definition is caught at submit time by validation rules on the grid and a post edit hook on the control table, so an administrator is told the problem while they can still fix it - rather than finding out when the EDIT screen stops working.

Worth knowing

  • Derived columns are an EDIT screen feature; the VIEW screen and the downloads do not show them.
  • Expressions only - no macro triggers, no semicolons, no comments. Conditional logic comes from functions such as ifc(), choosec(), cats(), put() and intnx().
  • An expression can reference a column that is hidden from the user by column level security, and the derived column will show the result. Configure derived variables with the same care as any other data exposure.

Read the details at Derived Variables. And if a table of yours has been waiting for "just one more column", book a discovery call - we like this sort of request.