Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composite unique contstraint with null values

How can I set a composite unique constraint that can properly handle null values in SQLite? This is likely better expressed by example:

CREATE TABLE people (
    id INTEGER PRIMARY KEY,
    first_name TEXT NOT NULL,
    last_name TEXT NOT NULL,
    suffix TEXT,
    UNIQUE (first_name, last_name, suffix)
);

The constraint works as expected when a person with a suffix is entered more than once.

-- Last insert is denied
INSERT INTO people (first_name, last_name, suffix)
VALUES
    ('Joe', 'Dirt', 'Sr'),
    ('Joe', 'Dirt', 'Jr'),
    ('Joe', 'Dirt', 'Sr');

However, the unique constraint is not accommodating when a person without a suffix is inserted more than once.

-- Both are permitted
INSERT INTO people (first_name, last_name)
VALUES
    ('Chris', 'Farley'),
    ('Chris', 'Farley');

I understand SQLite treats null values as independent from one another, but is there a way to get around this?


1 Answers

You can create a unique partial index for first_name and last_name only when suffix is null:

CREATE UNIQUE INDEX idx_people ON people(first_name, last_name) 
WHERE suffix IS NULL;

See a simplified demo.

If your version of SQLite is 3.31.0+, you could create a generated column which returns an empty string when suffix is null and use it in the unique constraint instead of suffix:

CREATE TABLE people (
    id INTEGER PRIMARY KEY,
    first_name TEXT NOT NULL,
    last_name TEXT NOT NULL,
    suffix TEXT,
    str_suffix GENERATED ALWAYS AS (COALESCE(suffix, '')),
    UNIQUE (first_name, last_name, str_suffix)
);
like image 193
forpas Avatar answered Oct 29 '25 15:10

forpas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!