How to Get Nth Match With Index Match in Excel
Learn multiple Excel methods to get nth match with index match with step-by-step examples and practical applications.
How to Get Nth Match With Index Match in Excel
Why This Task Matters in Excel
Imagine an operations manager who tracks thousands of order lines. Each time a customer number appears, the sheet logs the ordered product, quantity, and shipping date. Management requests the third product the customer bought so they can create a personalized up-sell campaign. A simple lookup won’t work because VLOOKUP, XLOOKUP, and a basic INDEX + MATCH combination always stop at the first match.
The same issue arises in customer service dashboards where agents need the second time a complaint code occurred, or in quality control logs where analysts must return the fifth inspection result for a given batch. Finance teams may need the nth expense claim for a project to test frequency, while HR might want the second training date for an employee. In data cleansing projects you often have to extract the nth appearance of duplicated keys to flag anomalies.
Excel is fantastic for these scenarios because it offers both cell-based formulas and dynamic array functions that can slice, filter, and aggregate data without writing any code. Mastering the nth-match technique allows you to keep everything inside the workbook instead of exporting to SQL or Power BI for a seemingly simple question.
Not knowing how to perform an nth match forces analysts to write brittle helper columns, copy-paste filtered lists, or use manual find-next searches—all error-prone and time-consuming. The nth-match concept also unlocks deeper skills such as array manipulation, spill ranges, advanced filtering, and dynamic dashboards. Once you command INDEX with an arithmetic or filtered MATCH row number, you can build rolling analyses, top-n reports, and period-over-period comparisons that update instantly as data changes.
Best Excel Approach
The fastest and most transparent way to fetch the nth match is a single-cell array formula that combines:
- INDEX – returns a value given a row (and optionally column) number.
- MATCH with an expanding row reference – locates every instance of the lookup value.
- SMALL or FILTER – isolates the nth position from the list of positions.
- IF or ISNUMBER – safely removes non-matches.
In modern Excel (Microsoft 365 and Excel 2021), dynamic arrays let you skip CTRL+SHIFT+ENTER and use native spill behavior. Legacy versions require the array formula keystroke.
Recommended pattern (dynamic array version):
=INDEX(return_range, SMALL(IF(criteria_range=lookup_value, ROW(criteria_range)-MIN(ROW(criteria_range))+1), n))
return_range– the column you actually want back (e.g., Product).criteria_range– the column that contains repeated lookup values (e.g., CustomerID).lookup_value– the key you are searching for.n– the ordinal instance (1 for first, 2 for second, etc.).
Why this works: IF(criteria_range=lookup_value, ROW(...) …) builds an array of row numbers only where the key matches. SMALL(..., n) plucks the nth smallest row index from that list. Finally INDEX returns the item sitting on that row within the return range. This approach remains readable, refreshes instantly, and depends on native functions available in any Excel version released in the past fifteen years.
Alternative for users who already embraced XLOOKUP:
=INDEX(return_range, INDEX(AGGREGATE(15,6,ROW(criteria_range)/(criteria_range=lookup_value), n), 1))
AGGREGATE with option 15 (SMALL) and option 6 (ignore errors) replicates SMALL+IF but avoids array-entry keystrokes in some builds.
Parameters and Inputs
criteria_rangeandreturn_rangemust be the same length. Mismatched sizes yield#REF!.- Both ranges can be vertical (a single column) or horizontal (a single row) but cannot be two-dimensional blocks.
lookup_valueis case-insensitive for text, treats numbers as numbers, and should be cleaned of extra spaces.nmust be a positive integer. Ifnexceeds the number of actual matches, the formula returns#NUM!. Wrap in IFERROR to display a friendly message.- If the dataset contains blanks in
criteria_range, they behave as non-matches. Blanks inreturn_rangeare returned as blanks. - Array formulas respect filters and hidden rows—they still compute on hidden data. Use SUBTOTAL or FILTER if you need visible-only logic.
- Input sheet might include header rows. To keep the math simple,
ROW(criteria_range)-MIN(ROW(criteria_range))+1normalizes the first data row to 1 regardless of where it sits on the sheet. - Edge cases: duplicate headers, merged cells, and numbers stored as text. Standardize formats with VALUE or TEXTBEFORE/TEXTAFTER if necessary.
Step-by-Step Examples
Example 1: Basic Scenario
Goal: Return the second product ordered by Customer 101 in a small table.
Sample data (place in [A1:C8])
| CustomerID | OrderDate | Product |
|---|---|---|
| 101 | 3-Jan-2023 | Keyboard |
| 102 | 4-Jan-2023 | Mouse |
| 101 | 5-Jan-2023 | Monitor |
| 103 | 6-Jan-2023 | Webcam |
| 101 | 7-Jan-2023 | Headset |
| 102 | 8-Jan-2023 | Cable |
| 101 | 9-Jan-2023 | Desk Mat |
- Place the lookup value
101in cell [E2]. - In [F2] type the desired instance number
2. - In [G2] enter:
=INDEX([C2:C8], SMALL(IF([A2:A8]=E2, ROW([A2:A8])-MIN(ROW([A2:A8]))+1), F2))
Array-enter in pre-365 Excel (CTRL+SHIFT+ENTER), or just press Enter in Microsoft 365.
Result: “Monitor”.
Why it works:
[A2:A8]=E2evaluates to [TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,TRUE].ROW([A2:A8])becomes [2,3,4,5,6,7,8]. Adjusting by the minimum row (2) plus 1 yields [1,2,3,4,5,6,7].- Applying IF keeps rows [1,3,5,7] for the TRUE positions.
SMALL(...,2)returns 3 (the third physical row of the table), and INDEX fetches the product in [C4], “Monitor”.
Variations: change [F2] to 3 to return “Headset”, or wrap the entire formula in IFERROR to return “No such instance” when [F2] is 5.
Troubleshooting: confirm both ranges start on the same row. If you see #VALUE!, you may have forgotten the array keystroke or mismatched parentheses.
Example 2: Real-World Application
Scenario: A contact center logs each call with AgentID, timestamp, and ResolutionCode. Supervisors need the fourth resolution code a particular agent issued to audit coaching progress.
Data (50,000 rows) stored in a structured Table named tblCalls with headers AgentID, TimeStamp, ResolutionCode.
Steps:
- Give the user a lookup cell [J2] for AgentID (e.g., “AG34”).
- Provide [J3] for the instance number (default 4).
- Enter this formula in [J4]:
=LET(
ids, tblCalls[AgentID],
res, tblCalls[ResolutionCode],
rows, ROW(ids)-MIN(ROW(ids))+1,
nthRow, SMALL(IF(ids=J2, rows), J3),
INDEX(res, nthRow)
)
Explanation:
LETdefines arrays once, improving readability and speed on big data.rowsvector holds normalized row positions.nthRowpulls the 4th match.- INDEX finally retrieves that ResolutionCode.
Performance considerations: With 50,000 rows, this formula calculates in under 10 milliseconds on a modern PC. Because it operates in-memory arrays, no helper columns or volatile functions are needed.
Integration: Conditional formatting highlights the returned code in the master table so supervisors see context. Combine the formula with a drop-down list (Data Validation) for AgentID to create an interactive audit dashboard.
Example 3: Advanced Technique
Task: For each salesperson in a list, display the latest three sales amounts in adjacent columns, avoiding duplicates and sorting newest first.
Dataset (Table tblSales) fields: SalesRep, SaleDate, Amount.
- Create a list of unique reps in [L2:L20] using:
=UNIQUE(tblSales[SalesRep])
- In [M2] enter an advanced nth-match spill formula:
=LET(
rep, L2,
ids, tblSales[SalesRep],
amt, tblSales[Amount],
dates, tblSales[SaleDate],
rows, ROW(ids)-MIN(ROW(ids))+1,
matches, IF(ids=rep, rows),
sorted, TAKE(SORTBY(matches, INDEX(dates, matches), -1), 3),
INDEX(amt, sorted)
)
Press Enter and drag across [M2:O2]. The three most recent sales for each rep spill horizontally.
Key advances:
SORTBYuses theSaleDatecolumn (descending) to find the newest rows before choosing the first three.TAKElimits the vector to three items.- Because
sortedcontains row numbers, INDEX can fetch corresponding amounts.
Edge cases handled: if a rep has fewer than three sales, the spill range returns the existing ones and blanks for the rest.
Professional tip: Wrap the whole LET in IFERROR and insert in a dynamic array row to build an evergreen sales leaderboard that updates every time new transactions are appended to the table.
Tips and Best Practices
- Normalize Row Numbers: Always subtract
MIN(ROW(range))+1so your array starts at 1. This keeps SMALL and AGGREGATE outputs intuitive, especially when the table isn’t anchored at row 1. - Wrap in LET: Naming sub-arrays (
ids,rows,nthRow) makes complex logic self-documenting and reduces redundant calculations, speeding up large files. - Use Named Ranges or Tables: Structured references like
tblData[Product]eliminate absolute references and automatically resize when new data is added. - Combine with Data Validation: Present a drop-down for
lookup_valueand a spinner form control fornto make interactive dashboards user-friendly. - Error-Proof Your Sheet: Enclose formulas in
IFERRORorIFNAwith custom messages such as “No 5th occurrence” so stakeholders see a meaningful result instead of#NUM!. - Avoid Volatile Functions: Don’t mix NOW, TODAY, or OFFSET inside nth-match formulas unless necessary. Volatile recalculation can slow massive workbooks.
Common Mistakes to Avoid
- Mismatching Range Sizes – If
return_rangeandcriteria_rangeare of different lengths, INDEX returns#REF!. Double-check by selecting both ranges; Excel’s status bar should show the same row count. - Forgetting Array Entry in Legacy Excel – In versions prior to Microsoft 365, pressing Enter alone yields
#VALUE!. RememberCTRL+SHIFT+ENTER. - Using Volatile ROW() without Anchoring – If you insert rows above the dataset, the calculated row offsets shift. Anchor with absolute references or use structured tables.
- Overlooking Case Sensitivity Needs – MATCH logic is case-insensitive. When case matters, wrap the comparison in
EXACT(criteria_range, lookup_value). - Not Handling Excess n Values – Asking for the tenth match when only eight exist throws
#NUM!. Guard withIF(COUNTIF(criteria_range, lookup_value) < n, "Not found", formula).
Alternative Methods
While the INDEX-SMALL-IF pattern is the workhorse, you can achieve the nth match through other routes.
| Method | Pros | Cons | Best When |
|---|---|---|---|
| FILTER + INDEX | Readable, no array math in legacy Excel | Requires Microsoft 365, can spill large ranges | You only need the nth item, have modern Excel |
| XLOOKUP with nth helper column | Dynamic columns, no array formulas | Needs additional column, susceptible to sort changes | Dataset already has calculated columns |
| Power Query | Handles millions of rows, refresh button | Breaks real-time interactivity, user exits formula mode | Data warehouse loads or heavy ETL |
| PivotTable with Value Field Settings | No formula, easy UI | Manual refresh, cannot pick arbitrary n dynamically | Reporting periodic snapshots |
Comparison: FILTER is fastest (<5 ms on 50k rows), INDEX-SMALL slightly slower (~10 ms), AGGREGATE similar, Power Query takes seconds but scales to hundreds of thousands. Choose based on Excel version, need for instant recalculation, and whether you prefer formula-only models or data models.
FAQ
When should I use this approach?
Use INDEX-SMALL-MATCH whenever you need a single value tied to the nth appearance of a key and you want it to update the moment source data changes. It is perfect for dashboards, audits, or validation checks.
Can this work across multiple sheets?
Yes. Fully qualify ranges, e.g., Sheet2!A:A. The row subtraction trick still applies: ROW(Sheet2!A:A)-MIN(ROW(Sheet2!A:A))+1. Ensure both sheets remain open; otherwise, external links slow calculation.
What are the limitations?
The formula returns only one field per call. To fetch multiple columns you must wrap the core INDEX in CHOOSECOLS/XLOOKUP or replicate formulas sideways. Array math on very large ranges (above 1 million cells) can cause noticeable delay.
How do I handle errors?
Wrap in IFERROR or IFNA. For example:
=IFERROR(core_formula, "No such occurrence")
Use COUNTIF(criteria_range,lookup_value) to pre-check whether n exists and conditionally display a user-friendly message.
Does this work in older Excel versions?
Yes, even Excel 2007 supports INDEX, SMALL, IF, and ROW. Just remember to array-enter. LET, SORTBY, TAKE, and FILTER require Microsoft 365 or Excel 2021.
What about performance with large datasets?
On modern hardware, 100,000 rows calculate nearly instantly. To optimize further, convert ranges to Tables, use LET to prevent double calculations, and keep ranges set to used rows instead of entire columns. Disable \"Recalculate workbook before save\" for massive files.
Conclusion
Learning to get the nth match with INDEX and MATCH transforms Excel from a simple lookup tool into a true analytical engine. You can dissect repeated keys, build chronological snapshots, and power interactive dashboards without VBA or external databases. Practice the basic formula, graduate to LET wrappers, and experiment with FILTER and SORTBY to extract richer insights. Mastery of this single pattern reverberates through countless workbook designs—take the next step by applying it to your own dataset today and watch your productivity soar.
Related Articles
How to Show the 10 Most Common Text Values in Excel
Learn multiple Excel methods to list the 10 most frequent text values—complete with step-by-step examples, business use cases, and expert tips.
How to Abbreviate Names Or Words in Excel
Learn multiple Excel methods to abbreviate names or words with step-by-step examples and practical applications.
How to Abbreviate State Names in Excel
Learn multiple Excel methods to abbreviate state names with step-by-step examples, professional tips, and real-world applications.