T-SQL IF...ELSE Statement
Master T-SQL IF...ELSE — Boolean conditions, BEGIN/END for multi-statement bodies, ELSE IF chains, nested IF, IF EXISTS pattern for row-existence checks, and common pitfalls including the missing END IF and NULL comparisons.
IF ... ELSE is T-SQL's basic conditional branch. You give it a Boolean expression; if it's TRUE the IF block runs, otherwise the optional ELSE block does. It works exactly like if/else in any other language — with one or two T-SQL-specific gotchas covered below.
- condition — any Boolean expression: comparison (
@x > 5), logical combination (a = 1 AND b = 2),EXISTS (SELECT ...), etc. - BEGIN ... END — needed only when the body has more than one statement. A single statement can sit directly after the
IFcondition.
END IF keyword. Unlike PL/SQL or shell scripts, you don't terminate an IF with anything special — it ends after its statement (or BEGIN/END block). Forgetting this is a common cause of "I added a second line and now the ELSE doesn't fire" bugs.ELSEIF (one word). Write ELSE IF condition with a space.DECLARE @value INT = 10;
IF @value > 5
PRINT 'Value is greater than 5';
DECLARE @value INT = 3;
IF @value > 5
PRINT 'Value is greater than 5';
ELSE
PRINT 'Value is 5 or less';
Multiple conditions checked in order, falling through to the next as each one fails:
DECLARE @value INT = 5;
IF @value > 10
BEGIN
PRINT 'Value is greater than 10.';
END
ELSE IF @value > 5
BEGIN
PRINT 'Value is greater than 5 but 10 or less.';
END
ELSE
BEGIN
PRINT 'Value is 5 or less.';
END
An IF can sit inside another IF's body — useful when one decision depends on another:
DECLARE @value INT = 7;
IF @value > 5
BEGIN
PRINT 'Value is greater than 5.';
IF @value > 10
BEGIN
PRINT 'Value is also greater than 10.';
END
ELSE
BEGIN
PRINT 'Value is 10 or less.';
END
END
ELSE
BEGIN
PRINT 'Value is 5 or less.';
END
One of the most useful patterns: branch on whether a query returns any rows. IF EXISTS is faster and clearer than IF (SELECT COUNT(*) FROM t) > 0 because the optimizer can stop at the first matching row:
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
Name NVARCHAR(50)
);
INSERT INTO Employees VALUES (1, 'Alice'), (2, 'Bob');
DECLARE @id INT = 2;
IF EXISTS (SELECT 1 FROM Employees WHERE EmployeeID = @id)
PRINT 'Employee found.';
ELSE
PRINT 'No employee with that ID.';
A typical business-logic example: pull a row of data, then branch on its values.
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
CustomerName NVARCHAR(50),
CreditLimit DECIMAL(10, 2),
OutstandingBalance DECIMAL(10, 2)
);
INSERT INTO Customers VALUES
(1, 'John Doe', 1000.00, 800.00), -- under limit
(2, 'Jane Smith', 1500.00, 1600.00), -- OVER limit
(3, 'Alice Johnson', 2000.00, 1500.00); -- under limit
DECLARE @CustomerID INT = 2,
@CustomerName NVARCHAR(50),
@CreditLimit DECIMAL(10, 2),
@OutstandingBalance DECIMAL(10, 2);
-- Pull the row into variables
SELECT @CustomerName = CustomerName,
@CreditLimit = CreditLimit,
@OutstandingBalance = OutstandingBalance
FROM Customers
WHERE CustomerID = @CustomerID;
-- Branch on the values
IF @OutstandingBalance > @CreditLimit
PRINT 'Warning: balance exceeds credit limit for ' + @CustomerName;
ELSE
PRINT 'Balance is within the credit limit for ' + @CustomerName;
Re-running with @CustomerID = 1 takes the ELSE branch instead:
- "Forgotten BEGIN/END" silent bugs. When an IF body is a single statement, only that one statement is conditional. If you later add a second line below it expecting it to be conditional too, it won't be — it'll always run. Wrap multi-statement bodies in
BEGIN ... END. - Truthy values don't exist in T-SQL.
IF @xis a syntax error — you need a real Boolean:IF @x <> 0orIF @x IS NOT NULL. - NULL is not FALSE.
IF @x = NULLis never true (becauseNULL = NULLis unknown). UseIF @x IS NULL. - Always use
IF EXISTSfor "row exists" checks rather thanSELECT COUNT(*)— short-circuits at the first match.
IF conditionruns the next statement (orBEGIN ... ENDblock) when the condition is TRUE; the optionalELSEhandles the FALSE case.- T-SQL has no
END IFkeyword — IF ends after its statement or block. Forgetting this leads to "added a second line and broke the ELSE" bugs. ELSE IFis two keywords with a space — notELSEIF.- Chains of
ELSE IF ... ELSEwork top-down; the first matching condition wins. For value-based selection, also consider theCASEexpression. - Use
IF EXISTS (SELECT 1 FROM ...)for "row exists" checks — fast and idiomatic. - Watch out for NULL: use
IS NULL/IS NOT NULL, never= NULL.