What do NTILE and PERCENT_RANK tell you?
They answer different questions about a distribution. NTILE divides the rows into equal-sized groups and labels them; PERCENT_RANK says where each row sits in the ordering as a fraction.
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name VARCHAR(120) NOT NULL,
lifetime_spend DECIMAL(12, 2) NOT NULL
);
INSERT INTO customers (id, name, lifetime_spend) VALUES
(1, 'Grace Hopper', 12500.00),
(2, 'Ada Lovelace', 5400.00),
(3, 'Joan Clarke', 5100.00),
(4, 'Alan Turing', 480.00),
(5, 'Claude Shannon', 300.00);
SELECT name,
lifetime_spend,
NTILE(4) OVER (ORDER BY lifetime_spend DESC) AS quartile,
ROUND(PERCENT_RANK() OVER (ORDER BY lifetime_spend DESC), 3) AS pct_rank
FROM customers
ORDER BY lifetime_spend DESC;Five rows come back. The quartiles are 1, 2, 3, 4 and 4, and the percent ranks are 0, 0.25, 0.5, 0.75 and 1.0.
NTILE(n) splits the rows into n buckets of as equal a size as possible and labels them 1 to n. With five rows and four buckets the first three buckets get one row each and the last gets two, because the remainder is spread over the leading buckets. It is a rank-based split, not a value-based one — a bucket can contain values that are wildly different if the distribution is skewed.
PERCENT_RANK is different. It computes (rank minus one) divided by (number of rows minus one), so the top row is 0, the bottom row is 1, and the values in between are evenly spaced. The closest relative neighbour is CUME_DIST, which is (rank) divided by (number of rows) and therefore starts at 1 divided by n rather than at 0.
The practical difference shows up in how you use them. PERCENT_RANK is the right tool for "the top 10 per cent of customers" — filter on pct_rank < 0.1 — because the fraction is a real proportion of the population. NTILE is the right tool for "divide customers into four spending bands", because it guarantees roughly a quarter of the customers land in each band.