sqlcmd.net validated sql reference
intermediate null-handling MySQL MariaDB SQL Server PostgreSQL SQLite

Compare Values Including NULLs Safely

Match rows where two values are equal, treating two NULLs as equal instead of unknown.

Docker-validated Not currently validation-green

Find rows where two nullable name columns match

Ada matches because both nullable columns are NULL. Bob matches because both columns contain Q. Carol and Dan do not match because only one side is NULL. A plain middle_name = preferred_middle_name predicate would return Bob only and silently miss Ada.

MySQL MariaDB
Engine-specific syntax
Setup
CREATE TABLE people (
  id INT,
  name VARCHAR(50),
  middle_name VARCHAR(50),
  preferred_middle_name VARCHAR(50)
);

INSERT INTO
  people (id, name, middle_name, preferred_middle_name)
VALUES
  (1, 'Ada', NULL, NULL),
  (2, 'Bob', 'Q', 'Q'),
  (3, 'Carol', NULL, 'R'),
  (4, 'Dan', 'X', NULL);
SQL
SELECT
  id,
  name
FROM
  people
WHERE
  middle_name <= > preferred_middle_name
ORDER BY
  id;
idname
1Ada
2Bob
SQL Server
Engine-specific syntax
Setup
CREATE TABLE people (
  id INT,
  name VARCHAR(50),
  middle_name VARCHAR(50),
  preferred_middle_name VARCHAR(50)
);

INSERT INTO
  people (id, name, middle_name, preferred_middle_name)
VALUES
  (1, 'Ada', NULL, NULL),
  (2, 'Bob', 'Q', 'Q'),
  (3, 'Carol', NULL, 'R'),
  (4, 'Dan', 'X', NULL);
SQL
SELECT
  id,
  name
FROM
  people
WHERE
  middle_name = preferred_middle_name
  OR (
    middle_name IS NULL
    AND preferred_middle_name IS NULL
  )
ORDER BY
  id;
idname
1Ada
2Bob
PostgreSQL
Engine-specific syntax
Setup
CREATE TABLE people (
  id INT,
  name VARCHAR(50),
  middle_name VARCHAR(50),
  preferred_middle_name VARCHAR(50)
);

INSERT INTO
  people (id, name, middle_name, preferred_middle_name)
VALUES
  (1, 'Ada', NULL, NULL),
  (2, 'Bob', 'Q', 'Q'),
  (3, 'Carol', NULL, 'R'),
  (4, 'Dan', 'X', NULL);
SQL
SELECT
  id,
  name
FROM
  people
WHERE
  middle_name IS NOT DISTINCT
FROM
  preferred_middle_name
ORDER BY
  id;
idname
1Ada
2Bob
SQLite
Engine-specific syntax
Setup
CREATE TABLE people (
  id INT,
  name TEXT,
  middle_name TEXT,
  preferred_middle_name TEXT
);

INSERT INTO
  people (id, name, middle_name, preferred_middle_name)
VALUES
  (1, 'Ada', NULL, NULL),
  (2, 'Bob', 'Q', 'Q'),
  (3, 'Carol', NULL, 'R'),
  (4, 'Dan', 'X', NULL);
SQL
SELECT
  id,
  name
FROM
  people
WHERE
  middle_name IS preferred_middle_name
ORDER BY
  id;
idname
1Ada
2Bob

The operator differs by engine, but all examples match both ordinary equal values and pairs where both values are NULL.

Where this command helps.

  • comparing nullable columns during data quality checks
  • joining or filtering rows where missing values should count as matching

What the command is doing.

Ordinary equality does not match two NULL values because NULL = NULL evaluates to unknown, not true. Null-safe equality fixes that when missing values should be considered equivalent. PostgreSQL supports IS NOT DISTINCT FROM; MySQL and MariaDB support the <=> operator; SQL Server uses an explicit (a = b OR (a IS NULL AND b IS NULL)) predicate; SQLite can use IS for null-safe value comparison.