Yes, you can run SQL in Excel — but only if you accept that Excel doesn’t have a built-in SQL engine, and what most people call "SQL" is really a mix of Power Query M expressions, ODBC passthroughs, and ancient Jet SQL remnants.
The Problem
You’ve got sales data pasted into Sheet1: unsorted, duplicated, with inconsistent region names and missing Q3 figures for two accounts. You need to pull 'all orders from Acme Corp or Veridian Dynamics where amount > $15,000 and date >= 2024-01-01'. You try typing SELECT * FROM [Sheet1$] WHERE... into a cell. It fails. You paste it into the Name Manager. Still fails. You Google "run sql in excel" and land on forums full of macros, add-ins, and warnings about enabling unsafe ActiveX controls.
| Customer | Region | Amount | Order Date | Status |
|---|---|---|---|---|
| Acme Corp | NA | $24,500 | 2024-02-11 | Shipped |
| Veridian Dynamics | EMEA | $12,800 | 2024-01-22 | Pending |
| Acme Corp | North America | $18,300 | 2024-03-15 | Shipped |
| Zephyr Labs | APAC | $31,600 | 2024-02-28 | Shipped |
| Veridian Dynamics | Europe | $16,900 | 2024-01-05 | Shipped |
| Acme Corp | NA | $9,200 | 2024-03-01 | Cancelled |
That’s six rows. But notice: "NA" vs "North America", "Europe" vs "EMEA", and a $9,200 order that shouldn’t be included. You don’t want to filter manually. You want declarative logic — like SQL.
The Solution
The cleanest, safest, and most maintainable way to run SQL-like queries in Excel is through Power Query — specifically using its Advanced Editor with SqlExpression in a custom ODBC connection, or better yet, using Power Query’s native Table.SelectRows and Table.Contains functions that mirror SQL intent without requiring external drivers.
Here’s how to do it in under 90 seconds:
- Select your data range (A1:E7), then go to Data → From Table/Range. Make sure "My table has headers" is checked. Click OK.
- In Power Query Editor, go to Home → Advanced Editor. Replace the auto-generated code with this:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Filtered = Table.SelectRows(Source, each ([Amount] > 15000) and
List.Contains({"Acme Corp", "Veridian Dynamics"}, [Customer]) and
[Order Date] >= #date(2024, 1, 1)),
Sorted = Table.Sort(Filtered,{{"Order Date", Order.Ascending}})
in
Sorted
This gives you exactly what you’d get from SELECT * FROM [Sheet1$] WHERE Amount > 15000 AND Customer IN ('Acme Corp','Veridian Dynamics') AND [Order Date] >= '2024-01-01' ORDER BY [Order Date]; — but it runs natively, no database needed.
| Step | Action | Result | Shortcut |
|---|---|---|---|
| 1 | Select A1:E7 → Data tab → From Table/Range | New Power Query query named "Query1" | Alt+A, T |
| 2 | Home → Advanced Editor → paste M code | Three rows returned, sorted by date | Alt+H, F, A |
| 3 | Home → Close & Load | Results appear in new worksheet as dynamic table | Alt+F, C |
The beauty of this approach is that it’s fully auditable, refreshable, and works offline. No server. No credentials. Just Excel + your data.
Going Further
You can use real SQL — but only via an ODBC connection to an external source. For example: create a connection to a local SQLite file (using the SQLite ODBC driver), then write actual SQL in a Microsoft Query window (Data → Get Data → From Other Sources → From Microsoft Query → [ODBC DSN]). That opens a classic query builder where you can type raw SQL like SELECT Customer, SUM(Amount) FROM Orders GROUP BY Customer HAVING SUM(Amount) > 25000.
Another lesser-known trick: Excel’s legacy QUERY function (Google Sheets users know this well) does not exist in Excel — but you can simulate it using FILTER, UNIQUE, and SORT. Try this in cell G1:
=FILTER(A2:E7,(E2:E7="Shipped")*(C2:C7>15000)*((A2:A7="Acme Corp")+(A2:A7="Veridian Dynamics")),"No matches")
What makes this elegant is that it’s volatile-free, requires zero Power Query setup, and updates instantly when source data changes — unlike Power Query, which needs manual or scheduled refresh.
When NOT to Use This
Don’t reach for Power Query SQL-like filtering if your dataset is under 500 rows and changes daily. The overhead isn’t worth it. Just use AutoFilter or SUMIFS/COUNTIFS.
Never use Jet SQL (via DAO or ADO in VBA) on .xlsx files — it only works reliably on .xls or Access databases. Attempting SELECT * FROM [Sheet1$] against modern Excel files will throw “Could not find installable ISAM” — even if you’re running 64-bit Office.
Also avoid embedding SQL strings inside CONCATENATE or TEXTJOIN formulas. One misplaced quote or bracket breaks everything — and Excel won’t tell you why. If you’re writing dynamic filters, use LAMBDA to encapsulate logic instead.
Keyboard Shortcuts
| Shortcut | Action | Use Case |
|---|---|---|
Alt + A, T |
Import data as Table (required before Power Query) | First step for any structured data import |
Alt + H, F, A |
Open Advanced Editor in Power Query | Edit M code directly — faster than clicking UI buttons |
Ctrl + Shift + F5 |
Refresh all Power Queries | Critical after source data changes |
Alt + F, C |
Close & Load (Power Query) | Finalize and push results to worksheet |