Anyone who has worked with SQL for any length of time learns the same lesson: SQL is extremely literal. It doesn't try to guess what you meant. It simply follows the rules.

That can be frustrating at first, but once you understand how SQL thinks, many of its quirks begin to make sense.

One of the most useful habits I learned came from a colleague who had a simple acronym:

SINIS

SUM(ISNULL())

In other words:

SUM(ISNULL(ColumnName,0))

Never:

ISNULL(SUM(ColumnName),0)

At first glance, both expressions appear to accomplish the same thing. Most of the time they even return the same result. But they solve two very different problems.

Understanding NULL

In SQL, NULL does not mean zero.

NULL means unknown or no value.

Suppose a sales table contains the following values:

Amount
100
NULL
250
NULL

If you execute:

SELECT SUM(Amount)

the result is:

350

The NULL values are ignored.

So why bother using ISNULL() at all?

The Hidden Problem

SQL Server's SUM() ignores NULL values, but NULL values inside row-level expressions can silently remove those rows from the aggregate.

Consider this query:

SELECT SUM(Price * Quantity)
FROM OrderLines;

If a row contains a NULL value for either Price or Quantity, the entire expression for that row becomes NULL, and SQL excludes that row from the total. That may be exactly what you want—or it may hide missing data that should have contributed to the calculation.

Handling NULL values before performing the calculation makes your intent explicit:

SELECT SUM(ISNULL(Price,0) * ISNULL(Quantity,0))
FROM OrderLines;

By replacing NULL values before the multiplication, every row contributes predictably to the aggregate.

Why SUM(ISNULL()) Is Better

Instead, replace every NULL before SQL performs the addition.

SELECT SUM(ISNULL(Amount,0))

Internally SQL sees:

Amount
100
0
250
0

The result is always a legitimate numeric total.

More importantly, you've made your intent explicit:

"Treat missing values as zero before calculating the total."

That intent is immediately obvious to the next programmer who reads your code.

What About ISNULL(SUM())?

Many developers write:

SELECT ISNULL(SUM(Amount),0)

This waits until after SQL performs the aggregation.

If every value is NULL, it converts the final NULL into zero.

While this often produces the same answer, it is solving a different problem:

"If the aggregate itself is NULL, replace it with zero."

Your aggregate is still operating on NULL values rather than numbers.

Why My Colleague Preferred SINIS

The colleague who taught me this never argued that ISNULL(SUM()) was always wrong.

His point was that consistent habits prevent subtle mistakes.

If every nullable value is converted before calculations occur:

SUM(ISNULL(...))
AVG(ISNULL(...))
MIN(ISNULL(...))
MAX(ISNULL(...))

your code behaves predictably, even as queries become more complicated.

Over time the habit becomes automatic.

"SINIS" was simply an easy way to remember it.

A Practical Example

Suppose you're producing monthly commission totals.

SELECT
    Salesperson,
    SUM(ISNULL(Commission,0)) AS TotalCommission
FROM Sales
GROUP BY Salesperson;

If some commissions haven't been entered yet, your totals still calculate correctly.

The report doesn't suddenly produce NULL because one value was missing.

The Takeaway

SQL rewards precision.

Small habits—consistent formatting, meaningful aliases, and remembering SINIS—can eliminate hours of debugging later.

Whenever you're aggregating nullable numeric columns, consider whether the data should be treated as zero before the calculation rather than fixing the result afterward.

Sometimes the smallest programming habits become the ones you rely on for an entire career.