Excel INDEX + MATCH – Complete Guide
📖 What is INDEX + MATCH?

INDEX + MATCH is a two-function combination where MATCH finds the position of a value in a range, and INDEX uses that position to return the corresponding value from another range. Together, they replicate and far exceed the capability of VLOOKUP — without any of its structural limitations.

Think of it as a two-step lookup engine: MATCH answers "which row (or column) is the value in?" and INDEX answers "what value is at that row (or column)?". Because the two functions are independent and composable, they work in any direction, survive column insertions, and enable advanced patterns like two-way matrix lookups and dynamic header-based retrieval.

📦 INDEX — The Retriever
=INDEX(array, row_num, [col_num])
Returns the value at a specific row/column position inside an array. Like going to row 4, column 2 of a table and reading the cell.
🔍 MATCH — The Finder
=MATCH(lookup_value, lookup_array, [match_type])
Returns the position number of a value within a range. Like finding "Rohan" is the 3rd name in a list — returns 3.
📚
Real-world analogy: INDEX is like going to a specific page of a book. MATCH is like using the index at the back to find the page number. Together: MATCH finds the page number → INDEX retrieves the content on that page.
FeatureVLOOKUPINDEX + MATCH
Search directionRight onlyAny direction (left, right, up, down)
Column insertion safe?Breaks (column numbers shift)Never breaks — uses range refs
Two-way (row + col) lookupNot possibleNative — INDEX(array, MATCH, MATCH)
Performance on large dataSlowerFaster — MATCH searches only 1 column
Column number required?Yes — hardcoded numberNo — uses actual range reference
Horizontal lookup?Need HLOOKUP separatelySame formula — just change to row
⚙️ Syntax & How It Works
── Full combined formula ────────────────────────────────────────
=INDEX( return_range, MATCH( lookup_value, lookup_range, 0 ) )

return_range     → The column/row from which to return the result (e.g., C2:C100)
MATCH(
  lookup_value   → The value you are searching for (cell ref or literal)
  lookup_range   → The column/row to search in (e.g., A2:A100)
  0             → Match type: 0 = Exact match (always use 0 for lookups)
)

── Common patterns ──────────────────────────────────────────────
=INDEX(C:C, MATCH(F1,A:A,0)) → Basic right lookup
=INDEX(A:A, MATCH(F1,C:C,0)) → Left lookup (impossible in VLOOKUP)
=INDEX(B:D, MATCH(F1,A:A,0), MATCH(G1,B1:D1,0)) → Two-way matrix lookup
=IFERROR(INDEX(C:C,MATCH(F1,A:A,0)),"Not Found") → With error handling
1
MATCH Searches
Scans lookup_range for the value. Returns its row position number.
2
Position Passed
MATCH result (e.g., 3) becomes the row_num argument inside INDEX.
3
INDEX Returns
INDEX fetches the value at that row from the return_range column.
ℹ️ Match type = 0 is critical: Always use 0 for exact match in business lookups. Using 1 or -1 (approximate match) requires a sorted list and returns wrong values on unsorted data silently. Two-way lookup pattern: =INDEX(data_range, MATCH(row_key, row_headers, 0), MATCH(col_key, col_headers, 0)) — INDEX receives two MATCH results, one for the row and one for the column.
📊 Example 1 — Left Lookup: Find Employee ID by Name
Basic Use Case

HR needs to find an Employee ID by searching the Name column — but the ID column is to the LEFT of the Name column. VLOOKUP cannot do this. INDEX + MATCH handles it natively with no column rearrangement needed.

A — Emp IDB — NameC — DepartmentD — CTC (₹)
EMP-101Aarav SharmaFinance12,00,000
EMP-102Priya MehtaHR8,50,000
EMP-103Rohan GuptaOperations9,20,000
EMP-104Sunita NairMarketing11,00,000
EMP-105Vikram DasSales7,80,000
// Search cell F1 = "Priya Mehta"
Step 1 — MATCH finds position:
  MATCH("Priya Mehta", B2:B6, 0) → returns 2 // 2nd name in B2:B6

Step 2 — INDEX retrieves from A (left column):
  INDEX(A2:A6, 2) → returns EMP-102
Find Employee ID by Name → =INDEX(A2:A6, MATCH(F1, B2:B6, 0))EMP-102
Find Department by Name  → =INDEX(C2:C6, MATCH(F1, B2:B6, 0))HR
Find CTC by Name          → =INDEX(D2:D6, MATCH(F1, B2:B6, 0))₹ 8,50,000
✅ Emp ID: EMP-102 🏢 Dept: HR 💰 CTC: ₹ 8,50,000
Why this beats VLOOKUP: The search column (B — Name) is to the RIGHT of the return column (A — Emp ID). VLOOKUP requires the search column to always be the leftmost column — making this scenario impossible without rearranging the data. INDEX + MATCH has zero such constraint — any column can be the lookup, any column can be the return.
📊 Example 2 — Two-Way Matrix Lookup (Row + Column)
Advanced / Practical Use Case

A Finance Manager has a product × region sales matrix. She wants to fetch the sales figure for any combination of Product and Region dynamically — by entering both values in dropdown cells. This requires two MATCH functions inside INDEX: one to find the row, one to find the column.

A — Product \ Region B — North C — South D — East E — West
Laptop 4,20,000 3,10,000 2,80,000 3,75,000
Mobile 2,50,000 1,90,000 2,10,000 1,60,000
Tablet 1,80,000 1,40,000 1,60,000 2,25,000
Headphones 95,000 72,000 88,000 1,05,000
// F1 = "Tablet" (Product), G1 = "West" (Region)
Step 1 — MATCH finds product row:
  MATCH("Tablet", A2:A5, 0) → returns 3 // Row 3 in the data

Step 2 — MATCH finds region column:
  MATCH("West", B1:E1, 0) → returns 4 // 4th header = West

Step 3 — INDEX retrieves intersection:
  INDEX(B2:E5, 3, 4) → returns ₹ 2,25,000
Product in F1 = "Tablet"   |   Region in G1 = "West"

Two-way lookup → =INDEX(B2:E5, MATCH(F1, A2:A5, 0), MATCH(G1, B1:E1, 0))
With error guard → =IFERROR(INDEX(B2:E5, MATCH(F1,A2:A5,0), MATCH(G1,B1:E1,0)), "Not Found")
✅ Tablet | West = ₹ 2,25,000 🗺️ Any combo works dynamically
Two-way lookup power: Change F1 to "Laptop" and G1 to "North" — the formula instantly returns ₹ 4,20,000. No formula edit needed. This pattern is used extensively in MIS dashboards, pricing grids, budget vs actual matrices, and commission slab tables — anywhere a row-column intersection needs to be retrieved dynamically.
💡 Key Applications
  • Finance Left lookup on chart of accounts — retrieve account names by searching GL codes in column B and returning account descriptions from column A, without restructuring the master file.
  • MIS Dynamic matrix dashboards — product × region, salesperson × month, branch × KPI grids where any row-column combination is selected via dropdown and the intersection is fetched in one formula.
  • HR Grade-based salary lookup — retrieve the exact CTC band for a given Grade and Department from a 2D salary matrix without hardcoding values or building helper columns.
  • Audit Column-insertion-safe reconciliation sheets — audit workbooks often have columns inserted/deleted during review. INDEX + MATCH formulas never break when this happens, unlike VLOOKUP.
  • Tax GST rate matrix lookup — fetch the applicable GST rate for a given product category and supply type (B2B/B2C/Export) from a two-dimensional rate table using double MATCH.
  • Sales Commission slab retrieval — given a salesperson's achievement % and product tier, retrieve the correct commission % from a 2D slab table — a classic two-way INDEX + MATCH application.
  • Retail Price list with reverse lookup — find the product name corresponding to a given barcode that appears in a middle column, returning data from columns both left and right of the search column.
⚠️ Common Mistakes to Avoid
1. Using Match Type 1 or -1 Instead of 0 (Exact Match)
Writing =INDEX(C:C, MATCH(F1, A:A, 1)) with match type 1 (approximate) on an unsorted list returns a completely wrong result silently — no error appears, just incorrect data. This is the most dangerous mistake in INDEX + MATCH.
Fix: Always use 0 for exact match in business data: =INDEX(C:C, MATCH(F1, A:A, 0)). Only use 1 or -1 on intentionally sorted ranges like tax slabs.
2. Return Range and Lookup Range Different Sizes
Writing =INDEX(C2:C10, MATCH(F1, A2:A8, 0)) where return range has 9 rows but lookup range has only 7 rows. MATCH returns a position relative to A2:A8, but INDEX uses it against C2:C10 — returning values from the wrong rows.
Fix: Keep both ranges exactly the same size and starting row: =INDEX(C2:C10, MATCH(F1, A2:A10, 0)). Safest: use full columns — =INDEX(C:C, MATCH(F1, A:A, 0))
3. No IFERROR Wrapper — Raw #N/A Errors in Reports
When the lookup value is not found, INDEX + MATCH returns a raw #N/A error. In client reports, dashboards, or printed MIS sheets, this looks unprofessional and can cascade into errors in dependent formulas.
Fix: Always wrap with IFERROR: =IFERROR(INDEX(C:C, MATCH(F1,A:A,0)), "Not Found") or use "" for blank, 0 for numeric fields.
4. Two-Way Lookup: Header Range Misalignment
In two-way lookup =INDEX(B2:E5, MATCH(F1,A2:A5,0), MATCH(G1,B1:E1,0)), if the column header range B1:E1 doesn't exactly match the data range columns B2:E5, MATCH returns a position that doesn't align with the data — pulling the wrong column value.
Fix: Ensure the column MATCH range (B1:E1) starts in the exact same column as the left edge of the data range (B2:E5). Cross-check by counting columns — both must be 4 wide.
5. Using INDEX + MATCH When XLOOKUP Is Available
In Excel 365 / 2019+, writing a complex INDEX + MATCH when XLOOKUP achieves the same result with simpler syntax adds unnecessary complexity — harder to read, harder to audit, and slower to build for straightforward single-direction lookups.
Fix: Use XLOOKUP for simple 1-directional lookups in Excel 365. Reserve INDEX + MATCH for two-way matrix lookups and backward-compatibility scenarios where XLOOKUP is unavailable.
Scroll to Top