INDEX MATCH Explained: The Ultimate Lookup Formula

โฑ๏ธ 5 min read ๐Ÿ“Š Excel

INDEX MATCH is a lookup formula built from two functions: MATCH finds the position of a value in one column or row, and INDEX returns the value at that same position from another range. Combined as =INDEX(return_range, MATCH(lookup_value, lookup_range, 0)), it works in every Excel version and, unlike VLOOKUP, can return a column to the left of the one you search.

Quick answer: Use =INDEX(return_range, MATCH(lookup_value, lookup_range, 0)). MATCH returns the position of the lookup value in the lookup column (0 means exact match), and INDEX returns the value at that position in the return column. For example, =INDEX(C2:C100, MATCH("John", A2:A100, 0)) finds "John" in column A and returns the value from column C on the same row. Both ranges must cover the same rows.

What do the INDEX and MATCH functions do?

INDEX returns the value at a given position in a range, and MATCH returns the position of a lookup value within a single row or column. Neither is a lookup on its own: MATCH answers "at which position?" and INDEX answers "what is at that position?"

INDEX: Returns a Value at Position

=INDEX(array, row_num, [column_num])

=INDEX(A1:A100, 5)
Returns the value in the 5th row of A1:A100

=INDEX(A1:C100, 5, 2)
Returns value at row 5, column 2 (B5)

MATCH: Finds the Position

=MATCH(lookup_value, lookup_array, [match_type])

=MATCH("Apple", A1:A100, 0)
Returns the position of "Apple" in the range
0 = exact match (use this for most lookups)

If "Apple" is in A8, returns 8

How do you combine INDEX and MATCH in one formula?

Put MATCH inside INDEX as the row_num argument: =INDEX(return_range, MATCH(lookup_value, lookup_range, 0)). MATCH finds the row where the lookup value sits, and INDEX returns the value on that row of the return range.

Basic Lookup (Replaces VLOOKUP)

=INDEX(return_range, MATCH(lookup_value, lookup_range, 0))

Example:
=INDEX(C2:C100, MATCH("John", A2:A100, 0))

Find "John" in column A, return corresponding value from column C

Worked Example: Step by Step

     A        B         C
1    Name     Dept      Salary
2    Alice    Sales     52000
3    Bob      IT        61000
4    Carol    Finance   58000

=INDEX(C2:C4, MATCH("Bob", A2:A4, 0))

Step 1: MATCH("Bob", A2:A4, 0)  returns 2      (Bob is the 2nd cell of A2:A4)
Step 2: INDEX(C2:C4, 2)         returns 61000  (the 2nd cell of C2:C4, which is C3)

The position is counted from the start of the range, not the top of the sheet. Bob is on worksheet row 3, but MATCH returns 2 because the range starts at row 2, which is why the lookup range and the return range must start on the same row.

Why This is Better Than VLOOKUP

What are some practical INDEX MATCH examples?

The three patterns you'll use most are a straight lookup (find an employee, return their salary), a left lookup that returns a column sitting to the left of the lookup column, and a two-way lookup that uses one MATCH for the row and a second MATCH for the column.

Salary Lookup

Data:
A2:A20 = Employee Names
D2:D20 = Salaries

=INDEX($D$2:$D$20, MATCH(E2, $A$2:$A$20, 0))

Looks up employee in E2, returns their salary
$ makes references absolute for copying down

Look Up to the Left

Data:
B2:B50 = Product Codes (lookup column)
A2:A50 = Product Names (return column - left of lookup!)

=INDEX($A$2:$A$50, MATCH("PROD-123", $B$2:$B$50, 0))

VLOOKUP can't do this!

Two-Way Lookup (Row AND Column)

Data table:
      Jan  Feb  Mar
Alice  100  150  200
Bob    120  180  220
Carol  110  160  210

=INDEX($B$2:$D$4,
    MATCH("Bob", $A$2:$A$4, 0),
    MATCH("Feb", $B$1:$D$1, 0)
)

Returns: 180

First MATCH finds Bob's row (2)
Second MATCH finds Feb column (2)
INDEX returns value at row 2, column 2

Advanced Techniques

Because MATCH can search a calculated array and supports approximate matching, INDEX MATCH also covers lookups on several criteria at once (VLOOKUP usually needs a helper column for that), the closest value below a threshold, and returning any column, or a whole row, from a table.

Multiple Criteria Lookup

Find row where First Name = "John" AND Last Name = "Smith"

=INDEX($D$2:$D$100,
    MATCH(1,
        ($A$2:$A$100=F2) * ($B$2:$B$100=G2),
    0)
)

Enter as array formula: Ctrl + Shift + Enter (older Excel)
Excel 365: Just press Enter

The * creates AND logic (1 only when both match)

See how to enter an array formula if you're on Excel 2019 or earlier, and INDEX MATCH with multiple criteria for three or more conditions and what happens when several rows match.

Lookup Closest Match Below

Tax brackets, shipping tiers, volume discounts:

Sorted data:
A2:A10 = Income thresholds (ascending order)
B2:B10 = Tax rates

=INDEX($B$2:$B$10, MATCH(C2, $A$2:$A$10, 1))

Match type 1 = closest value less than or equal
REQUIRES sorted data in ascending order!

Return Multiple Columns

=INDEX($A$2:$E$100, MATCH("John", $A$2:$A$100, 0), 3)

Returns column 3 (C) for John's row

Change the last number (3) to return different columns:
1 = column A, 2 = column B, etc.

Use 0 to return the whole row (Excel 365/2021 spills it):
=INDEX($A$2:$E$100, MATCH("John", $A$2:$A$100, 0), 0)

Error Handling

When MATCH can't find the lookup value it returns #N/A, and INDEX passes that error through. Wrap the whole formula in IFNA (Excel 2013 and later) to replace only #N/A, or in IFERROR to replace any error; IFNA is safer because IFERROR also hides #REF! and #VALUE! errors caused by mistakes in the formula itself.

Safer (only replaces #N/A):
=IFNA(INDEX($C$2:$C$100, MATCH(E2, $A$2:$A$100, 0)), "Not Found")

Basic error handling:
=IFERROR(
    INDEX($C$2:$C$100, MATCH(E2, $A$2:$A$100, 0)),
    "Not Found"
)

Shows "Not Found" instead of #N/A error

Check if exists first:
=IF(COUNTIF($A$2:$A$100, E2) > 0,
    INDEX($C$2:$C$100, MATCH(E2, $A$2:$A$100, 0)),
    "Not in list"
)

Should you use INDEX MATCH, VLOOKUP or XLOOKUP?

Use XLOOKUP when everyone who opens the file has Microsoft 365 or Excel 2021 or later, and INDEX MATCH when the workbook must also work in older versions; both look in any direction and survive inserted columns. VLOOKUP is fine for quick lookups to the right, but its column number breaks when columns move. For typical sheets the three run at about the same speed, so choose on compatibility and readability (see VLOOKUP vs XLOOKUP).

Feature VLOOKUP INDEX MATCH XLOOKUP
Direction Right only Any direction Any direction
Column changes Breaks Resilient Resilient
Speed (typical data) About the same About the same About the same
Compatibility All versions All versions 365 & 2021+
Two-way lookup Only with MATCH as col_index_num Yes Yes (nested XLOOKUP)

Why does INDEX MATCH return #N/A or the wrong value?

Usually because the lookup value is not an exact match for what is in the cell (a number stored as text, a trailing space), MATCH's match_type was left out, or the lookup and return ranges don't line up. MATCH ignores case, so "apple" and "Apple" are not the problem.

Pro Tip: Use INDEX MATCH for maximum compatibility across Excel versions. Use XLOOKUP if you're certain all users have Excel 365/2021+. For two-way lookups (row AND column), INDEX with two MATCHes works in every version; in Excel 365/2021+ a nested XLOOKUP does the same: =XLOOKUP("Bob", A2:A4, XLOOKUP("Feb", B1:D1, B2:D4)).

โ† Back to Excel Tips