Expert guide

Access 'Query Is Too Complex' Error: Causes and Fixes

Rewrite the parts that exceed the engine's limits, and the query usually gets faster too

Short answer: the Access engine refuses queries whose internal plan is too large. The usual culprits are long nested IIf chains, dozens of OR conditions, big UNION queries, many joins and very long SQL. Replace IIf chains with a lookup table join (or Switch), replace OR lists with IN or a criteria table, build results in stages with saved queries, and push heavy work to SQL Server views if the data lives there. Our Access optimisation work often starts with these rewrites.

"Query is too complex" usually appears in a database that has grown organically: a commission rule added here, a new region there, until one query carries years of business logic in a single SQL statement. Access has no setting to raise the limit. The fix is to restructure the query, which almost always makes it easier to maintain as well.

Cause 1: Nested IIf Chains

The problem:
Tier: IIf([Sales]<1000,"Bronze",IIf([Sales]<5000,"Silver",IIf([Sales]<10000,"Gold",
      IIf([Sales]<25000,"Platinum",IIf([Sales]<50000,"Diamond","Elite")))))
      ... repeated for 12 regions with different thresholds

Fix A: a lookup table (best)

tblTiers: Region | MinSales | MaxSales | Tier

SELECT s.*, t.Tier
FROM tblSales AS s
INNER JOIN tblTiers AS t
   ON s.Region = t.Region
  AND s.Sales >= t.MinSales AND s.Sales < t.MaxSales;

This is a non-equi join: it cannot be shown in the query design grid, only in SQL view, but Access runs it fine. The business can now change thresholds in a table instead of a developer editing SQL.

Fix B: Switch for a moderate list

Tier: Switch([Sales]<1000,"Bronze", [Sales]<5000,"Silver",
             [Sales]<10000,"Gold", True,"Elite")

Fix C: a VBA function for genuinely complex rules

Public Function GetTier(ByVal region As String, ByVal sales As Currency) As String
    Select Case region
        Case "North", "East": GetTier = IIf(sales >= 20000, "Gold", "Silver")
        Case Else:            GetTier = IIf(sales >= 15000, "Gold", "Silver")
    End Select
End Function

In the query:  Tier: GetTier([Region], [Sales])

VBA functions in queries are slower on large tables and do not work in pass-through queries or on SQL Server, so prefer the lookup table where possible.

Cause 2: Long OR Lists

Instead of:
WHERE [ProductCode]="A12" OR [ProductCode]="B44" OR ... (60 more)

Use IN:
WHERE [ProductCode] In ("A12","B44","C07", ...)

Or a criteria table:
WHERE [ProductCode] In (SELECT Code FROM tblSelectedProducts)

Forms with many check boxes that build OR conditions should write the selected values into a temporary criteria table and join to it.

Cause 3: Big UNION Queries

  • A UNION of many monthly or branch tables usually means data is split into tables that should be one table with a Month or Branch column. Consolidating them removes the need for the union.

  • If you must union, use UNION ALL (no duplicate removal) and build it in two or three smaller saved unions combined at the end.

  • Alternatively, append each part into a temporary table, then query that table.

Cause 4: Too Much in One Query

Build the result in stages. Stage one filters and joins the core tables, stage two adds calculations, stage three aggregates. Each saved query is simple; the final query uses the previous one as its source.

StageSaved queryDoes
1qryOrders_BaseJoin orders, lines, customers; filter by date range
2qryOrders_CalcAdd margin, tier (via lookup join), flags
3qryOrders_SummaryGroup by region and month for the report

Cause 5: Updates on Tables With Many Validations or Indexes

An UPDATE that sets many fields at once on a table with many indexes, validation rules or multivalued fields can also raise the error. Split it into two or three updates of fewer fields, or update through a recordset in VBA.

When the Data Is on SQL Server

If tables are linked from SQL Server, rewrite heavy queries as server views or pass-through queries. They run entirely on the server, avoid Access's limits and return far less data over the network. The translation approach is in AI-assisted Access to SQL Server migration.

Use AI to Untangle a Monster Query

Prompt:
This Microsoft Access query returns "Query is too complex".
Rewrite it as (1) a lookup table design replacing the nested IIf,
(2) a set of 2–3 saved queries that build the same result in stages,
and (3) the SQL for each, using Access SQL syntax.
Keep column names identical so the report still works.
[paste SQL]

See using ChatGPT to write Access SQL for prompting tips, and test the rewrite against the old results before replacing anything. If the query feeds a report that is also slow, the reports and forms service covers redesigning both.

FAQ

Query too complex FAQ

IIf, OR, UNION and engine limits

The Access database engine has internal limits on how complicated a single query can be. Long chains of nested IIf expressions, many OR conditions, union queries with many parts, many joined tables, very long SQL text and some combinations of subqueries can exceed them. The same error also appears when updating a table with very many indexed or validated fields in one statement.

Replace it with a lookup table joined in the query, or with the Switch function for moderate lists, or with a small VBA function for genuinely complex logic. A lookup table is usually best: it is fast, easy to maintain, and business users can update it without touching SQL.

Yes. Building the result in stages, where each saved query does part of the work and the next one uses it, often stays within the engine's limits and is easier to read and debug.

Access documents several specifications, such as a maximum of 255 fields in a query result, 32 tables in a query, about 64,000 characters in a SQL statement, and limits on nesting depth. The 'too complex' error can occur before any single documented limit is reached, because the engine's internal plan is the constraint.

Heavy queries rewritten as SQL Server views or pass-through queries run on the server engine, which handles far more complex statements. Simply linking tables to SQL Server without rewriting the query does not help, because Access still processes it.