Power Query basics: steps, M and query folding
Power Query is the data preparation engine behind Power BI Desktop, Excel, dataflows and Fabric Dataflow Gen2. You click transformations, it records each one as a step, and the steps are written in a formula language called M. The decision rule for exam questions: merge adds columns, append adds rows, and a transformation that can be translated into the source’s own query language “folds” and runs at the source, which is faster than running it in Power Query. Most scenario questions are one of those three ideas in disguise.
What a refresh actually runs
Microsoft describes an M script as a recipe for preparing the data. The Applied steps list in the Query settings pane is a friendly view of that recipe: each step is a named line of M that takes the previous step’s table and returns a new one. Power Query does not edit the source; it stores the steps and replays them on every refresh.
Here is a small query as the Advanced Editor shows it. The step names are what the Applied steps pane lists, and the quoted names (#"...") are quoted identifiers, the M way of allowing spaces in a name:
let
Source = Sql.Database("ServerName", "SalesDb"),
Orders = Source{[Schema = "dbo", Item = "Orders"]}[Data],
#"Filtered Rows" = Table.SelectRows(Orders, each [OrderDate] >= #date(2026, 1, 1)),
#"Removed Other Columns" = Table.SelectColumns(#"Filtered Rows", {"OrderID", "CustomerID", "Amount"}),
#"Changed Type" = Table.TransformColumnTypes(#"Removed Other Columns", {{"Amount", type number}})
in
#"Changed Type"
The query returns whatever follows in. Each step refers to the one above it by name, so deleting or reordering a step can break the ones below it. That dependency is why the editor warns you when you insert a step in the middle. Rename steps to say what they do; Microsoft’s best-practice page recommends meaningful names and descriptions.
Query folding: who does the work
Query folding is Power Query translating supported steps into a query the data source can run. In the script above, a SQL Server source can take the filter and the column selection and return only the rows and columns needed. When a step cannot be translated, Power Query pulls the data and does the rest itself in its own engine.
Microsoft’s documentation names three outcomes:
| Outcome | What happens |
|---|---|
| Full folding | The source processes all the transformations |
| Partial folding | The source does the steps that translate, Power Query does the remainder |
| No folding | The source returns the raw data, Power Query does everything |
Three facts are worth memorising. Sources with a query engine, such as SQL Server and OData feeds, commonly support folding, while files such as CSV and Excel workbooks do not, because there is no engine to hand work to. Folding generally stops at the first step that cannot be translated, and the steps that depend on it run locally; Microsoft’s own example is adding a “Capitalize each word” transform, which never folds (the documentation notes rare exceptions, such as removing that column again, where a later step can fold). And you can check: in Power Query Online, folding indicators sit beside each step, and where the connector supports it, right-clicking a step shows View Native Query (or View data source query). The indicators are available only in Power Query Online, not Desktop.
The practical rule from the Power Query best-practice guidance is to filter early and do expensive operations such as sorting last. Put the row filter and column removal right after the source, so they fold and the engine never sees the rows you did not need.
Merge versus append
| Merge | Append | |
|---|---|---|
| Direction | Horizontal: adds columns | Vertical: adds rows |
| Needs | Matching key column(s) of the same data type in each table | Tables whose columns line up by name; missing columns become null |
| Choices | Join kind | Two tables, or three or more |
| Result | New column holding the right table, which you expand | One table with all rows |
Merge matches rows by key and offers six join kinds: left outer (all rows from the left table plus matches), right outer, full outer, inner (matches only), left anti (rows only in the left table) and right anti. The left table is the first you select, and Microsoft notes that position matters for choosing the join kind. The key columns need the same data type or the join returns wrong results. A merge adds a column of nested tables, which you expand or aggregate.
Append stacks tables and matches columns by name, not position. If one table lacks a column the other has, the result gets nulls there. Both commands have an “as new” variant that leaves the source queries unchanged. A standard pairing is appending monthly extracts into one fact table, then merging a lookup table to add a category name. In M, a merge is written as Table.NestedJoin with a join kind such as JoinKind.LeftOuter, and an append as Table.Combine.
For the shape the loaded tables should take, see star schema and modelling; the storage side is covered in semantic model storage modes.
Which exams test this
| Exam | How the topic appears | Where on this site |
|---|---|---|
| PL-300 | Prepare the data (25–30%): connect to sources and set credentials and privacy levels, create parameters, profile and clean data, change data types, pivot and unpivot, merge and append queries, choose between reference and duplicate queries, and configure data loading. This is the core Power Query domain | Prepare the data explained |
| DP-600 | Prepare data (45–50%): merge or join data, convert column data types, handle duplicates and nulls, and select, filter and aggregate with the Visual query editor. The outline does not name Power Query or Dataflow Gen2, so this is an indirect topic: Dataflow Gen2 is one of the tools that can do these steps | Prepare data explained |
| DP-700 | Implement and manage an analytics solution and Ingest and transform data (30–35% each): choose Dataflow Gen2 versus a pipeline, notebook, KQL or T-SQL. Monitor and optimize adds resolving Dataflow Gen2 errors. Tested at the level of tool choice, not M | Implement and manage explained |
How the questions are built
The scenario states what the result must look like, and the answer is the transformation that produces it:
- Rows or columns? “Combine monthly files into one table” is append. “Add the region name to each sale” is merge. Mixing them up is the commonest wrong answer.
- Which join kind. “Customers who have never ordered” is a left anti join; “only orders that have a matching customer” is inner; “keep every order, even without a customer” is left outer.
- Reference or duplicate. A reference follows later changes to the original’s steps, a duplicate copies the steps and stays independent.
- Slow refresh. The fix is usually to filter earlier, remove unneeded columns, or avoid a step that breaks folding, not to change the storage mode.
- Source type. CSV and Excel never fold, so options that promise folding for them are wrong.
Question 1. You maintain a query on a SQL Server table with 200 million rows. The query keeps only rows from the current year, removes unused columns, and then applies the Capitalize Each Word transformation to a customer name column. Refresh is slow. You want the most rows filtered at the source. What should you do?
- A. Make sure the row filter and column removal come before the Capitalize Each Word step
- B. Move the Capitalize Each Word step to the top, before the filter
- C. Append the table to a copy of itself
- D. Export the table to a CSV file and connect to the file instead
Show answer
Answer: A
Folding stops at the first step that cannot be translated into the source query, and Capitalize Each Word does not fold. If the row filter and column removal come before it, they fold and the source returns only the reduced data, so the local text transformation runs on far fewer rows. Moving the capitalize step earlier would generally stop the later filter from folding. Appending a copy of the table adds rows. Switching the source to CSV removes folding entirely, since files have no query engine.
Question 2. You have a Sales query and a Customers query. You need a list of customers that have no rows in Sales, with Customers as the first table in the Merge dialog. Which join kind should you use?
- A. Inner
- B. Left outer
- C. Full outer
- D. Left anti
Show answer
Answer: D
A left anti join returns only the rows from the left table that have no match in the right table, which gives customers without sales when Customers is on the left. An inner join returns only customers that do have sales. A left outer join returns every customer, matched or not, so you would still need to filter. A full outer join returns rows from both tables. Append would stack the tables and match nothing.
Go deeper
- Query evaluation and query folding in Power Query
- Merge queries overview and append queries
- Best practices when working with Power Query
- Next: DAX basics for what happens after the data loads, and SQL joins and window functions for the same join logic in T-SQL. Study order is in how to study for certification exams.