Most schemas model corporate acquisitions as a join table: acquirer_id, target_id, price, closed_date. Some add is_completed BOOLEAN.
That boolean is where the model starts lying to you.
Four states a boolean cannot hold
An acquisition is not binary. Working through several hundred company profiles, the deals refuse to sit in two buckets:
Announced but not closed. In July 2026 Uber announced a voluntary takeover offer for Delivery Hero, around $14.8 billion, with closing expected in the second half of 2027 subject to conditions and regulatory approval. If your pipeline writes that row with is_completed = false, it will be indistinguishable from a deal that collapsed. If it writes true, you have just booked $14.8B of M&A that has not happened.
Closed, then unwound. Uber bought Drizly in 2021 for about $1.1 billion, ran it as a standalone service, and shut it down in 2024, folding alcohol ordering into Uber Eats. The acquisition completed. The entity no longer exists. Both facts are true and a boolean holds neither well.
Closed, then divested. McDonald's took a stake in Chipotle in 1998 and had fully divested by 2006. Financially it was one of the best investments in restaurant history. Strategically it was abandoned. "Completed" is accurate and useless.
Closed with partial disposal. The Uber–Delivery Hero offer earmarks 14 overlapping markets for separate sale to SSW Partners. The deal, if it closes, is simultaneously an acquisition and a divestiture.
A state field that survives contact
CREATE TYPE acquisition_status AS ENUM (
'announced', -- disclosed, not closed
'terminated', -- announced, then abandoned
'completed', -- closed, target operating
'absorbed', -- closed, brand retired into acquirer
'shuttered', -- closed, operations discontinued
'divested' -- closed, later sold on
);
Two things this buys you immediately:
-
announcedrows can be excluded from any "total M&A spend" aggregate with a single predicate, instead of relying on every downstream consumer to remember. -
shutteredanddivestedbecome queryable. "Which acquirers shut down what they bought?" is a genuinely interesting question and a boolean makes it unanswerable.
Add status_as_of DATE alongside it. Status is a point-in-time claim, not a permanent property, and without a date you cannot tell a stale row from a current one.
The counting trap
The related mistake: treating a row count as a fact about the world.
If a profile documents five acquisitions, that means five acquisitions are documented. It does not mean the company made five. Undisclosed deals, asset purchases and acqui-hires routinely never surface. Name the column acquisitions_documented rather than acquisition_count and the ambiguity disappears at the point of use, which is where it matters.
Worked example
If you want a deal-by-deal record with stated purpose and actual outcome for each — including the pending Delivery Hero offer explicitly flagged as pending rather than counted — the Uber acquisition history is laid out that way.
The general principle is boring and keeps paying: model the states your data actually occupies, not the two states that were convenient when the table was created.
Top comments (0)