What does DISTINCT actually deduplicate, and how does it decide that two rows are the same?
DISTINCT removes duplicate rows from the result set, and a row here means the whole projected row. Two rows are duplicates if every column in the projection has the same value in both. That means the comparison is over the entire select list, not over the column you happen to be looking at.
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name VARCHAR(120) NOT NULL,
city VARCHAR(80) NOT NULL,
tier VARCHAR(20) NOT NULL
);
INSERT INTO customers (id, name, city, tier) VALUES
(1, 'Ada Lovelace', 'London', 'gold'),
(2, 'Grace Hopper', 'New York', 'gold'),
(3, 'Alan Turing', 'London', 'gold'),
(4, 'Katherine Johnson', 'Hampton', 'gold');
-- These four rows are all distinct: the names differ.
SELECT name, city FROM customers;
-- These two rows are the same pair, so one survives.
SELECT DISTINCT city, tier FROM customers ORDER BY city;The second query returns three rows: London with gold, New York with gold, and Hampton with gold. The two London-and-gold rows collapsed into one, while New York and Hampton appeared once each already, so they survived unchanged. Note what the comparison is over: the pair, not the city alone. Had London appeared once with silver and once with gold, both would have been kept, because the full rows differ.
Two consequences follow. First, DISTINCT on a projection containing id does nothing at all, because a primary key is already unique — a common confusion when someone expects DISTINCT to dedupe by name. Second, DISTINCT compares NULLs as equal to each other, so rows that differ only in a nullable column collapse into one, and the surviving row keeps one of the NULLs.
The other thing to know is cost. DISTINCT forces the engine to compare rows, which usually means a sort or a hash aggregate over the whole result, and it happens after the projection. If a query is unexpectedly slow, the usual culprit is a DISTINCT added to silence a join that was producing duplicates it should have been aggregating instead.