HR wants Beacon Robotics' employees split into 4 salary quartiles per department, top earners in bucket 1, lowest in bucket 4, for a compensation review. NTILE() does exactly that, no manual bucketing math required.
Learning Objectives
- Define NTILE(N) precisely, and the bucketing problem it solves.
- Write NTILE() with PARTITION BY and ORDER BY to build quartile-style groups.
- Explain exactly what happens to the remainder when rows don't divide evenly into N groups.
Partition's Rows
Ordered by salary
NTILE(4)
Split into 4 groups
Remainder Distributed
Earliest groups get the extra rows
Bucket Number, 1 to N
Per row
What NTILE() Actually Does
NTILE(N) divides the rows in a partition, in ORDER BY order, into N as-equal-as-possible buckets, labeling each row with its bucket number from 1 to N. It's the function behind quartiles (NTILE(4)), deciles (NTILE(10)), and any other even split into a fixed number of groups.
Splitting Employees Into Salary Quartiles
Within each department, the highest-paid employees land in quartile 1, the lowest-paid in quartile 4.
SELECT first_name, last_name, department_id, salary,
NTILE(4) OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_quartile
FROM employees;When Rows Don't Divide Evenly
11 employees split with NTILE(4) can't form four perfectly equal groups of 2.75. The standard behavior, the same on every database in this course, gives the extra rows to the earliest groups first: 3 rows in group 1, 3 in group 2, then 3 in group 3 (here you'd expect 2 each, but 11 ÷ 4 leaves 3 remainder across the first 3 groups), 2 in group 4. The exact pattern for 11 rows into 4 groups is 3, 3, 3, 2, the first three groups each absorb one extra row before settling into the even base size.
Try It Yourself
Write a query splitting all employees company-wide into 2 halves by salary (above-median vs below-median), on SQL Server.
SELECT first_name, salary,
NTILE(2) OVER (ORDER BY salary DESC) AS salary_half
FROM employees;Frequently Asked Questions
Is NTILE() the same thing as PERCENTILE_CONT() or PERCENTILE_DISC()?
No, NTILE() assigns each row to one of N discrete buckets based on its position in the order. PERCENTILE_CONT()/PERCENTILE_DISC() instead compute a specific percentile value (like the 90th percentile salary) as a single number, not a per-row bucket label, covered in a later module.
Can NTILE(N) produce fewer than N groups?
Yes, if the partition has fewer rows than N, some bucket numbers simply won't be used, a 3-row partition with NTILE(4) only ever produces buckets 1, 2, and 3, bucket 4 stays empty because there's nothing left to put in it.
Common Beginner Mistakes
Assuming every NTILE() bucket has exactly the same number of rows
Only true when the partition's row count divides evenly by N. Otherwise, the earliest bucket numbers absorb the extra rows, one at a time, until the remainder is used up, the buckets are only ever as equal as the row count allows.
Forgetting ORDER BY and getting a meaningless bucket assignment
NTILE() needs an ORDER BY to know which rows count as "earliest" for bucketing, without one the grouping is arbitrary and not reproducible. Always include a clear ORDER BY, usually the same column the buckets are meant to represent.
Best Practices
- Use NTILE() specifically for a fixed number of roughly-equal groups, like quartiles or deciles, not for finding a single cutoff value.
- Always pair NTILE() with an explicit ORDER BY, the bucketing is meaningless without one.
- Expect the first few buckets to carry any extra rows when the count doesn't divide evenly, don't assume perfectly equal sizes.
Interview Questions
Write a query splitting employees into 4 salary quartiles within each department.
SELECT first_name, last_name, department_id, salary, NTILE(4) OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_quartile FROM employees; — PARTITION BY department_id restarts the quartile grouping for each department, ORDER BY salary DESC puts the highest earners into quartile 1.
If a department has 10 employees and NTILE(4) is applied, how many rows land in each quartile?
10 divided by 4 is 2 with a remainder of 2, so the first 2 groups absorb one extra row each: quartile 1 gets 3 rows, quartile 2 gets 3 rows, quartile 3 gets 2 rows, quartile 4 gets 2 rows. The remainder is always distributed to the earliest groups first, never randomly and never to the last group first.
Summary
NTILE(N) splits a partition's rows into N roughly equal buckets, numbered 1 to N in ORDER BY order, the standard tool behind quartiles, deciles, and similar fixed-count groupings. When the row count doesn't divide evenly, the earliest bucket numbers absorb the extra rows, identically across every database in this course.
What's Next?
SQL LAG() and LEAD() are next: looking at a preceding or following row's value directly, without a self-join.
Ready to Practice SQL?
Write and run real SQL queries online, right in your browser, no install or signup required. Pick a playground based on which database you want to practice on.
Both open a third-party SQL playground in a new tab. External site terms and privacy policy apply.
Or try 50 SQL practice questions →