Analistable

How to answer questions across multiple spreadsheets

By the Analistable team · Updated · 12 min read

Most questions that span several spreadsheets fall into four patterns: what's in one list but not the other, what changed between two periods, totals across many files, and facts that need two tables joined (customers and their orders). Stack files that share columns, join files that share a key, then filter or group. The pages below work through real examples with formulas and SQL.

The four question patterns

Patterns, examples and the operation behind them
PatternExample questionOperation
MembershipWhich leads never became customers?Anti join (rows with no match)
ChangeWhich customers stopped ordering this month?Join two periods, compare
Roll-upWhat are the top products across all stores?Stack files, then group
EnrichmentWhich ticket priorities do our biggest accounts raise?Join, then group

Stack or join first?

Files that share columns (one export per store or per month) are stacked into one long table — see combining Excel sheets into one. Files that share a key (customer ID, SKU, email) are joined side by side — see joining spreadsheets. Many questions need both: stack twelve monthly order files, then join them to the customer list.

A quick test: put the two header rows next to each other. If they are mostly the same, stack. If they share one or two identifying columns and the rest differ, join. If they share nothing, you need a mapping table first, such as a list that links product codes in one system to SKUs in another.

Getting the files ready to answer questions

Questions fail more often because of the shape of the files than because of the formula. Ten minutes of preparation saves an afternoon of wrong answers.

  1. One table per sheet, headers in row 1, no title rows, merged cells or subtotal lines inside the data. Turn each range into an Excel table (Ctrl+T, or Cmd+T on a Mac) so formulas can refer to Orders[Customer] instead of fixed ranges.
  2. One grain per table: one row per order, or one row per order line, but not both in the same sheet. Mixing them double-counts when you sum.
  3. A clean key in every file you will join: the same customer ID format, trimmed, in the same case. Email addresses are a reasonable key if you lower-case them; names usually aren't.
  4. Real types: dates as dates, amounts as numbers. A date stored as text cannot be filtered by month, and a number stored as text will not sum.
  5. Known coverage: note the date range of each export. A “September” file that stops on the 28th makes the last two days look like lost customers.

Pattern 1: membership — in one list but not the other

Membership questions ask which records appear in list A and not in list B: leads that never bought, invoices with no payment, registrants who didn't attend, products in the catalogue that never sold. The operation is an anti join.

The same membership test in four tools
ToolHow
Excel 365 / Google Sheets=FILTER(A[Email], COUNTIF(B[Email], A[Email]) = 0)
Excel 2019 and earlierHelper column =COUNTIF(B!A:A, A2) = 0, then filter on TRUE
Power QueryMerge Queries with the Left Anti join kind
SQLSELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.email = a.email)

Always run the test in both directions. Leads with no customer record is one question; customers with no lead record (people who bought without ever filling in a form) is a different and often surprising one. Recipes: leads that never became customers, unpaid invoices older than 30 days and registrations against attendance.

Pattern 2: change between two periods

Change questions compare the same measure across two files: last month and this month, last year's price list and this year's, the budget and the actuals. Group each period to the level you care about (one row per customer, per product, per region), then put the two side by side with a full outer join so records that exist in only one period are kept, with zero for the missing side.

In a spreadsheet, the easiest version is a pivot table over both periods stacked together, with Period in the columns. A Change column is then a simple subtraction. In SQL:

SELECT COALESCE(a.customer, s.customer) AS customer,
       COALESCE(a.amount, 0) AS august,
       COALESCE(s.amount, 0) AS september,
       COALESCE(s.amount, 0) - COALESCE(a.amount, 0) AS change
FROM aug a
FULL OUTER JOIN sep s ON s.customer = a.customer
ORDER BY change, customer;

More recipes: month-over-month growth from monthly files, comparing two price lists and comparing two quotes line by line.

Pattern 3: roll-ups across many files

Roll-up questions need every file stacked before they can be grouped: top products across all stores, revenue by month across a year of exports, a ranking of sales reps across regional files. The stacking method depends on where the files live.

Stacking methods
WhereMethodNote
Several sheets in one Excel workbook=VSTACK(North:West!A2:E500)Excel 365; 3D reference stacks every sheet between the two
Several sheets in Google Sheets={North!A2:E; South!A2:E; West!A2:E}Semicolons stack vertically; wrap in QUERY or FILTER to drop blank rows
A folder of Excel or CSV filesPower Query From Folder → CombineRefresh picks up new files
Any files, in SQLUNION ALLColumns must be listed in the same order

Add a column that says where each row came from (store, region, month) before or while stacking. Without it, you can total everything but can't break the total down. Recipes: top products and customers across stores and ranking sales reps across regional files.

Pattern 4: enrichment — join, then group

Enrichment questions need a fact from one file to be grouped by an attribute in another: support tickets by customer tier, returns by supplier, revenue by the sales rep who owns the account. Join the detail table (tickets, order lines) to the lookup table (customers, products), then group.

The trap is a lookup table with duplicate keys. If a customer appears twice in the customer list, every one of their tickets is counted twice after the join. Check first: =COUNTIF(Customers[ID], [@ID]) > 1 flags duplicates, or in SQL SELECT id, COUNT(*) FROM customers GROUP BY id HAVING COUNT(*) > 1. Recipes: support tickets against customer accounts, products with high return rates and late deliveries by supplier.

The same question in a formula and in SQL

“Which customers ordered last month but not this month?”, with each month's orders in its own sheet:

=UNIQUE(FILTER(Last[Customer], COUNTIF(This[Customer], Last[Customer]) = 0))
SELECT DISTINCT l.customer
FROM last_month l
LEFT JOIN this_month t ON t.customer = l.customer
WHERE t.customer IS NULL;

The formula works inside Excel or Google Sheets; the SQL is what a database (or Analistable, behind the scenes) runs. Both return the same list.

Before you trust the answer

  • Check the key: trailing spaces and different capitalisation make matching rows look missing.
  • Check for duplicates: a customer listed twice in a lookup table doubles their totals after a join.
  • Check the period: make sure both files cover the dates you think they do.
  • Sanity-check totals: the sum after a join should equal the sum before it, unless rows were meant to drop out.

Asking in plain language

Analistable loads your Google Sheets, Excel and CSV files into an in-browser database. You confirm which columns link the files, then ask a question such as “which customers stopped ordering in September?”. It writes read-only SQL, runs it on your computer and shows both the answer and the query. The question pages linked below show the data, the formula, the SQL and the result for each pattern.

Your rows never leave the browser — see our privacy policy.

A worked example: three questions, one dataset

Take two monthly order exports and a customer list. Three useful questions come from the same three files:

Questions and the operations behind them
QuestionFiles usedOperationResult in our example
Who stopped ordering?August, September ordersAnti join on customerHart & Co, Kiln Studio
Who's new?August, September ordersAnti join the other wayOak & Ash, Pine Co
What did new customers spend?September ordersFilter to new, then sum125 of 345 (36%)

Each answer takes one formula or one short SQL query, and none needs the files copied together by hand. Worked versions: customers who stopped ordering and new customers this month.

Here is the data behind those answers, one total per customer per month:

Order totals by customer
CustomerAugustSeptember
Bakery Lune150120
Hart & Co90
Kiln Studio60
Nordic Supply100100
Oak & Ash80
Pine Co45
Total400345

Running the change query from Pattern 2 on these rows gives the fourth, and often most useful, answer — *where* the 55 drop came from:

Query result: change by customer, largest fall first
customeraugustseptemberchange
Hart & Co900-90
Kiln Studio600-60
Bakery Lune150120-30
Nordic Supply1001000
Pine Co04545
Oak & Ash08080

Revenue fell from 400 to 345, a drop of 55 (13.75%). Lost customers took away 150, a smaller order from Bakery Lune another 30, and new customers added back 125: −150 − 30 + 125 = −55. That breakdown is far more useful than the headline number, and it needed both files joined, not just summed.

A second worked example: tickets by customer tier

Enrichment answers go wrong quietly, so it's worth seeing the trap with numbers. A support export has six tickets: three from customer C1, one from C2 and two from C3. The customer list gives each customer a tier, but C3 was entered twice when the account was migrated.

Tickets per tier, before and after removing the duplicate customer row
TierCustomersTickets (duplicate C3 row)Tickets (de-duplicated)
GoldC1, C375
SilverC211
Total86

The join turned six tickets into eight, because each of C3's two tickets matched both C3 rows. The check that catches it is simple: the ticket count after the join must equal the ticket count in the export (six). If it doesn't, look for duplicate keys before reading anything into the result. In a spreadsheet, XLOOKUP would not show this problem, because it returns only the first match; Power Query merges, pivot tables over the Data Model and SQL joins all would.

Answering across Google Sheets and Excel files together

Real questions often span tools: the customer list lives in a shared Google Sheet, the orders come from an Excel or CSV export. There are three practical routes:

  • Bring everything into Google Sheets: upload the Excel file to Drive, open it as a Google Sheet and use IMPORTRANGE or plain cross-tab references. Good for small files that colleagues edit together.
  • Bring everything into Excel: download the Google Sheet as .xlsx or CSV and load it into Power Query alongside the other files. Good when the result feeds an Excel report, but the download is a snapshot that goes stale.
  • Query both in place: a tool that reads the Google Sheet and the local files together and joins them, so the sheet stays live and nothing is copied by hand. See combining data from multiple sources.

Whichever route you take, check that the key columns survive the trip: Google Sheets and Excel can both turn long numeric IDs into scientific notation or drop leading zeros when a file is converted. Format ID columns as text before exporting.

Asking precise questions

Whether you write the formula yourself or ask a tool, vague questions get vague answers. A precise question names the measure, the grain, the period and the rule for edge cases.

Vague and precise versions of the same question
VaguePrecise
Who are our best customers?Top 10 customers by total order value, January–September 2026, excluding refunded orders
Which customers left?Customers with at least one order in Q2 and none in Q3
Are sales up?Total revenue by month for the last 12 months, with the change on the previous month
Which products have problems?Products with more than 20 units sold and a return rate above 10% this year

Writing the precise version first also tells you which files you need: the third question needs twelve months of orders stacked; the fourth needs orders and returns joined on product.

Troubleshooting answers that look wrong

Symptoms, causes and fixes
SymptomLikely causeFix
Everyone appears in the “not in the other list” resultKeys differ in case, spaces or type (number vs text)Clean both keys with TRIM and LOWER; convert IDs to one type
Totals are higher after a join than beforeDuplicate keys in the lookup table multiply rowsDe-duplicate the lookup table or aggregate it first
Totals are lower after a join than beforeInner join dropped rows with no matchUse a left join and count the rows with no match
A month is missing from a roll-upOne file failed to load or has a different headerCount rows per source after stacking
Change figures look too largePeriods have different lengths or one export is partialCheck the first and last date in each file
Customer counts don't match the CRMCounting rows instead of distinct customersUse COUNTA(UNIQUE()) or COUNT(DISTINCT customer)

Making it a monthly routine

Most cross-sheet questions come back every month. Save the work so the next answer takes minutes:

  • Keep each month's export with the same file name pattern and the same columns, in one folder or one set of tabs.
  • Build the question once as a Power Query, a formula sheet or a saved SQL query, and point it at the new file each month.
  • Record the answer alongside the row counts and date ranges of the inputs, so next month's comparison starts from known numbers.
  • When the source system changes its export (a renamed column is common), fix the mapping in one place rather than in every formula.

Question recipes by area

When the two files are records of the same activity that should agree, the question is a reconciliation; see reconciling data in Excel.

Choosing the right tool

Where to answer cross-sheet questions
SituationBest fit
A one-off question on two small filesCOUNTIF / XLOOKUP / FILTER in Excel or Google Sheets
The same question every monthPower Query, refreshed with new files
Many files, or questions you didn't plan forSQL — or Analistable, which writes it for you
Millions of rowsA database or DuckDB rather than a spreadsheet

Every guide in this topic

Frequently asked questions

How do I analyse data from multiple spreadsheets?
Stack the files that share columns, join the files that share a key, then filter or group the combined table with formulas, a pivot table or SQL.
Do I need SQL to compare spreadsheets?
No. COUNTIF, XLOOKUP, FILTER and pivot tables answer most questions. SQL is easier for multi-step questions, and tools like Analistable write it for you.
What's the most common cross-sheet question?
Which records are in one list but not the other — new customers, lapsed customers, missing invoices. It's an anti join, or COUNTIF = 0 in a spreadsheet.
Can I ask questions across Google Sheets and Excel files together?
Yes. Export one format to match the other and join them in Excel or Sheets, or connect both in Analistable, which loads them into one in-browser database and answers across both.
Why does my total go up after joining two sheets?
The lookup table has duplicate keys, so each matching row is repeated. De-duplicate the lookup table, or total it per key before joining.
How do I compare two months when some customers only appear in one?
Use a full outer join (or a pivot table over both months stacked together) so customers from either month are kept, with zero for the month they're missing from.