What COALESCE Really Does
The Microsoft documentation defines it in one clean sentence:
NULL, it returns NULL.
Think of it as a waterfall. The function walks its arguments left to right, and as soon as it finds a value that isn't NULL, it returns it and stops. Everything after is ignored.
Our Sample Table
Most employee records store a name in three separate columns — first, middle, and last. In real datasets, not every person has all three filled in. Let's build this exact scenario.
CREATE TABLE Employees (
EmpId INT PRIMARY KEY,
FirstName VARCHAR(30) NULL,
MiddleName VARCHAR(30) NULL,
LastName VARCHAR(30) NULL
);
INSERT INTO Employees VALUES
(1, 'Rohan', 'Kumar', 'Sharma'),
(2, NULL, 'Priya', 'Verma'),
(3, NULL, NULL, 'Kapoor'),
(4, 'Aditi', 'Lakshmi', 'Iyer'),
(5, 'Vikram', NULL, NULL),
(6, NULL, NULL, NULL);
The requirement: build a single Name column for every employee using this rule —
FirstName if it's not NULL.MiddleName if it's not NULL.LastName.Writing this as nested CASE or ISNULL calls would be painful. COALESCE solves it in one line.
The COALESCE Query
SELECT EmpId,
COALESCE(FirstName, MiddleName, LastName) AS Name
FROM Employees;
Result:
| EmpId | FirstName | MiddleName | LastName | Name (COALESCE) |
|---|---|---|---|---|
| 1 | Rohan | Kumar | Sharma | Rohan |
| 2 | NULL | Priya | Verma | Priya |
| 3 | NULL | NULL | Kapoor | Kapoor |
| 4 | Aditi | Lakshmi | Iyer | Aditi |
| 5 | Vikram | NULL | NULL | Vikram |
| 6 | NULL | NULL | NULL | NULL |
Row 1 and row 4 have all three names filled, but only the FirstName is picked — that's the priority rule at work. Row 2 falls back to MiddleName, row 3 falls back to LastName, and row 6 ends up as NULL because every argument was NULL.
How COALESCE Evaluates — Step by Step
This left-to-right short-circuit behaviour is not just a convenience — it also helps performance, because SQL Server doesn't need to compute any expression after the first non-NULL.
Giving a Final Default Value
Notice that row 6 still came back as NULL because all three name columns were empty. In reports we usually don't want that — we want a readable label. Just add a constant string as the last argument.
SELECT EmpId,
COALESCE(FirstName, MiddleName, LastName, 'Unknown') AS Name
FROM Employees;
Now row 6's Name is 'Unknown' — clean, readable output for your business users.
Real-World Use Cases Beyond Names
Contact fallback
COALESCE(Mobile, Office, Email, 'No Contact')Price fallback
COALESCE(SalePrice, OfferPrice, RegularPrice)Address priority
COALESCE(DeliveryAddress, BillingAddress, HomeAddress)Setting override
COALESCE(UserPref, TeamPref, GlobalPref)Language fallback
COALESCE(UserLang, BrowserLang, 'en')Date fallback
COALESCE(EndDate, LastActiveDate, GETDATE())Bonus — Building Full Names with COALESCE
COALESCE also plays well with CONCAT when you want a cleanly-spaced full name, even if some parts are missing:
SELECT EmpId,
CONCAT_WS(' ',
COALESCE(FirstName, ''),
COALESCE(MiddleName, ''),
COALESCE(LastName, '')) AS FullName
FROM Employees;
Here COALESCE(col, '') replaces each NULL with an empty string, and CONCAT_WS joins them with a single space — no awkward double spaces or trailing NULLs.
COALESCE vs ISNULL — The Quick Recap
| Feature | COALESCE | ISNULL |
|---|---|---|
| Number of arguments | 2 or more | Exactly 2 |
| ANSI standard? | Yes — works across databases | No — SQL Server specific |
| Return type | Picks highest-precedence type across all arguments | Always first argument's type (may truncate) |
| Best for | Priority chains, multi-column fallback | Simple single-column default |
| Performance | Almost identical in most real cases | Almost identical in most real cases |
Things to Watch Out For
1. All-NULL result. If every argument is NULL, COALESCE returns NULL. Put a constant as the last argument to guarantee a value.
2. Data type precedence. All arguments should be of compatible types. Mixing INT and VARCHAR may force an implicit conversion or throw an error — convert explicitly with CAST or CONVERT when types differ.
3. At least one non-NULL argument is required. COALESCE(NULL, NULL) with two literal NULLs fails to compile in some contexts — there must be at least one non-null-typed expression, or a data type must be declarable. Using COALESCE(CAST(NULL AS VARCHAR(10)), NULL) works.
4. Empty string is not NULL. A column containing '' (empty string) is not NULL, and COALESCE will return it gladly. If you want empty-string to be treated as missing, combine with NULLIF:
-- Treat empty string as missing, then fall back
SELECT COALESCE(NULLIF(FirstName, ''),
NULLIF(MiddleName, ''),
NULLIF(LastName, ''),
'Unknown') AS Name
FROM Employees;
5. COALESCE is an expression, not a statement. You can use it anywhere a value is expected — in SELECT, WHERE, ORDER BY, GROUP BY, JOIN conditions, computed columns, and even inside other expressions.
Internally, COALESCE Is a CASE Expression
A little-known fact — the SQL Server optimizer rewrites COALESCE into an equivalent CASE expression at parse time. These two are equivalent under the hood:
-- COALESCE version
COALESCE(FirstName, MiddleName, LastName)
-- Equivalent CASE version (what SQL Server really runs)
CASE
WHEN FirstName IS NOT NULL THEN FirstName
WHEN MiddleName IS NOT NULL THEN MiddleName
ELSE LastName
END
This is why COALESCE is portable, short-circuits cleanly, and gives accurate type resolution — it's CASE with nicer syntax.
The Interview Answer
"
COALESCE is an ANSI-standard SQL function that returns the first non-NULL value from a list of expressions, evaluated left to right with short-circuit behaviour. I use it for priority-based selection — like picking a FirstName if present, else MiddleName, else LastName, else a default label. It's more flexible than ISNULL because it accepts many arguments and handles return types more predictably. Internally, SQL Server rewrites COALESCE into a CASE expression, so it's effectively a cleaner way to write a fallback chain."
Summary
COALESCE is the go-to SQL Server function for priority-based value selection — "give me the first thing that actually exists". Pass it a left-to-right list of columns or expressions; the first non-NULL wins, and everything after is ignored. If everything is NULL, you get NULL back — so add a constant as the final argument to guarantee a readable value.
Use it for consolidated names, contact fallbacks, price hierarchies, language preferences, or any time real-world data has "try this, or that, or the other". It's short, it's portable, it's fast, and behind the scenes it's really just a tidy CASE expression. Master it, and a surprising number of ugly nested ISNULL/CASE chains will quietly disappear from your codebase.
| Concept | Key Takeaway |
|---|---|
| Definition | Returns the first non-NULL value from its arguments |
| Evaluation | Left to right with short-circuit behaviour |
| Argument count | Two or more (no upper limit in practice) |
| All-NULL input | Returns NULL unless a constant default is supplied |
| Primary use | Priority chains and column fallback |
| vs ISNULL | More arguments, ANSI standard, safer return type |
| Under the hood | Translated into a CASE expression |
| Empty string trap | Wrap with NULLIF(col, '') to treat blanks as missing |
| Works everywhere | SELECT, WHERE, ORDER BY, JOIN ON, computed columns |
| Interview keyword | "First non-NULL" + "ANSI standard" + "short-circuit" |