POWER QUERY TEMPLATE

Power Query recipes in Power Query Studio

Grouped by task. Each entry gives the query name in the workbook, what it does, what the starter data gives and what to watch for. The list is generated from the same manifest the workbooks are built from.

Cleaning

  • Clean text, Thai digits and Buddhist-era dates

    q01_Clean · Beginner

    Fixes hidden spaces, Thai digits, amounts and mixed date formats

    Starter data gives: 366 rows in the starter data; problems are kept in ParseErrors

    Watch out: Dates with / are read as day/month/year only. US order is never guessed

  • Keep the latest revision, deterministically

    q02_Deduplicate · Intermediate

    Deduplicates with UpdatedAt, then InputRow as the tie-breaker

    Starter data gives: 360 OrderIDs after removing 6 revisions

    Watch out: When timestamps tie, the row that comes later in the combined source wins. Define a stable sequence in real work

  • Route bad rows back to the source

    q03_Exceptions · Beginner

    Shows the raw value and the reason instead of silently dropping rows

    Starter data gives: 6 rows need fixing

    Watch out: Fix them in inSales_* and refresh. Never edit the output table

Combining and matching

  • Merge masters, net sales and cost

    q04_SalesModel · Intermediate

    Builds a sales table ready for reporting

    Starter data gives: 354 rows; total net sales on the Dashboard

    Watch out: An unknown product is not given a cost of 0, so profit is never overstated

  • Find customers missing from the master

    q05_AntiJoin · Beginner

    Left anti join for records that fell through

    Starter data gives: Finds one row for C999

  • Full outer reconciliation

    q06_Reconcile · Intermediate

    Separates one-sided items and amount differences

    Starter data gives: 4 refs: Matched / Amount differs / Ledger only / Bank only

  • Fuzzy match with a score and a review queue

    q18_FuzzyMatch · Advanced

    Finds similar names but leaves the decision to a person

    Starter data gives: Candidates and scores come from Excel's own fuzzy engine at refresh

    Watch out: Similarity is not a probability. Never approve or overwrite the master automatically

  • As-of join: the price in force on the order date

    q22_AsOfPrice · Advanced

    Uses the latest price effective on or before the order date

    Starter data gives: First 20 rows, to show the principle

    Watch out: A per-row lookup is expensive on large data. Use a temporal join in the database where you can

  • Compare New / Changed / Deleted

    q23_Changes · Advanced

    Finds differences against a separately stored snapshot

    Starter data gives: A unchanged, B changed, C deleted, D new

    Watch out: Refresh does not keep the old snapshot for you. Store history outside the query output

  • Match the master valid at the time

    q24_SCD2 · Advanced

    EffectiveFrom includes its start day; EffectiveTo excludes its end day

    Watch out: This uses an existing SCD2 table. It is not a system that records history into a database

Summaries and ranking

  • Group by month and channel

    q07_Monthly · Beginner

    Totals with transaction counts and missing cost

    Starter data gives: 27 groups (9 months x 3 channels)

    Watch out: KnownCost only sums costs that exist; profit is null for any group with missing cost

  • Top N by region

    q08_TopN · Intermediate

    Ranks within a group from a parameter

    Starter data gives: TopN products per region, set in Settings

  • Running total by channel

    q15_RunningTotal · Advanced

    Sorts first, then restarts the total inside each group

    Watch out: List.Accumulate per list suits small to medium data. Use a database for large volumes

  • 3-month moving average

    q16_RollingAverage · Advanced

    Averages 3 real calendar months and fills empty months with 0

    Watch out: The first 2 months average what exists in the range, and a month with no sales is assumed to be 0

  • Dense rank within a group

    q17_DenseRank · Advanced

    Ties share a rank and no rank is skipped

    Starter data gives: East: 1,1,2 and West: 1

  • Customer RFM and segments to watch

    q19_Customer360 · Advanced

    Summarises last purchase date, frequency and spend

    Watch out: The 60-day / 15-order thresholds are for demonstration, not a model that fits every business

  • Cohort retention by first purchase month

    q20_Cohort · Advanced

    Counts returning customers against the starting cohort

    Watch out: Cohorts start from the history in this file, not a lifetime first purchase. Empty cells are not filled with 0

  • ABC / Pareto for products

    q21_ABC · Advanced

    Shows cumulative share and product importance

    Watch out: Uses the share before the current row, so a product straddling 80% stays in A

Reshaping tables

  • Unpivot months that keep growing

    q09_Unpivot · Beginner

    Turns Jan/Feb/... columns into dated rows

    Starter data gives: 9 rows from 3 departments x 3 months

  • Pivot channels into dynamic columns

    q10_Pivot · Intermediate

    Builds a comparison without naming each channel

    Starter data gives: 9 months with a column per channel

  • Repair a report with blank group headers

    q11_FillDown · Beginner

    Blank to null, then Fill Down in the right order

    Starter data gives: 4 rows, TOTAL excluded

  • Split several values in one cell into rows

    q12_SplitRows · Beginner

    Splits comma-separated tags and trims spaces

    Starter data gives: 5 tags from 3 tickets

  • Accept files whose column names differ

    q31_SchemaDrift · Advanced

    Maps names, selects a common schema and keeps missing columns as null

    Starter data gives: A=100 B=200 Region=null

    Watch out: The common schema drops Extra on purpose. Never drop important data in real work

  • Unfold a two-row header

    q32_MultiHeader · Advanced

    Fills the group header across, builds column names, then unpivots

    Starter data gives: 8 rows from 2 regions x 2 months x 2 metrics

Dates and calendars

  • Fiscal calendar and business days

    q13_Calendar · Intermediate

    Builds a date dimension without a source file

    Starter data gives: 273 days from 2026-01-01 up to 2026-10-01

    Watch out: FiscalYear is named by the year the period ends. Holidays are sample data

  • Count SLA days, skipping weekends and holidays

    q14_BusinessDays · Intermediate

    States clearly whether the start and end days count

    Starter data gives: Start and end days included, business days only

  • Filter a date range with parameters

    q35_DateParameters · Beginner

    StartDate included, EndDate excluded, so period edges never overlap

    Watch out: Changing the range does not change the Dashboard, which uses all data. q35 is a separate filtered set

  • Fill dates with no transactions via a calendar join

    q36_GapFill · Intermediate

    Shows zero-sales days while keeping every date row

    Watch out: 0 means no transaction in the file. It does not prove the source sent everything

Advanced techniques

  • Unfold a reporting line with recursion

    q25_Hierarchy · Advanced

    Builds the path and level, and detects cycles

    Starter data gives: 5 employees and their reporting lines

    Watch out: The recursive function stops with an error on a cycle or a missing parent

  • Explode a multi-level BOM

    q26_BOM · Advanced

    Multiplies quantities through every level and sums repeated leaves

    Starter data gives: 10 KITs need leaf parts SCREW 140 and PANEL 20

    Watch out: LEG is an intermediate part, so it is not in the leaf result. The 10 is a demo run size; change the fxBOM argument

  • Select columns by pattern and transform them together

    q37_DynamicTransform · Intermediate

    Converts every column that starts with Amount_ automatically

    Starter data gives: 1250 / 40 and 999 / -10

  • A custom incremental window

    q39_IncrementalWindow · Advanced

    Half-open filter for reading data in batches

    Watch out: This Excel query does not accumulate history and is not a Power BI incremental refresh policy. A local source is still read in full before the filter

JSON, XML, HTML and APIs

  • Unfold nested JSON records and lists

    q27_JSON · Intermediate

    Turns orders/items into a detail table

    Starter data gives: 3 order lines totalling 850

  • Offline API pagination

    q28_Pagination · Advanced

    List.Generate fetches the next page until an empty one

    Starter data gives: 5 records from 3 pages with data, stopping at empty page4

    Watch out: The sample uses page numbers with an empty-page sentinel. A cursor API needs different state

  • Turn XML into a table

    q29_XML · Intermediate

    Reads XML text with repeating items

    Starter data gives: 3 items in the XML

    Watch out: Real XML may carry namespaces or attributes. Inspect the structure before expanding

  • Read an HTML table with a CSS selector

    q30_HTML · Intermediate

    Picks only the target table from HTML

    Starter data gives: 3 products, no web connection needed

Data quality

  • Profile every column

    q33_Profile · Intermediate

    Checks null / distinct / min / max before using the data

    Watch out: The profile covers the rows the query processed in full and can be heavy at a million rows

  • Flag outliers with IQR

    q34_Anomaly · Advanced

    Finds extreme values using quartiles

    Starter data gives: The value 100 is an outlier

    Watch out: Treat it as a signal to review. Never delete data automatically

  • Assertions for invariants and edge cases

    q38_Tests · Advanced

    Repeatable tests of the logic

    Starter data gives: 10 assertions, evaluated by Excel at every refresh

    Watch out: Passing assertions does not mean every connector works or every master is complete

  • Time and row counts of the last refresh

    q40_RefreshAudit · Intermediate

    Reads row counts and a runtime timestamp after refresh

    Watch out: The table is overwritten every time. It is not a running log and does not prove every other query refreshed

Connecting real sources

  • Combine a folder of CSV files with per-file status

    c01_FolderCSV · Connector

    Filters extensions and hidden files and records why a file failed

    Watch out: c01 is a file check report; use c01b to combine the data. A file with the wrong schema stops c01b

  • Combine Excel tables from many workbooks

    c02_FolderExcel · Connector

    Picks the Transactions table from every xlsx

    Watch out: Every file needs a Table named Transactions, not just a sheet name. Do not point it at the folder holding this workbook

  • Paged REST with bounded retry

    c03_REST · Connector

    Uses RelativePath/Query and keeps secrets out of the code

    Watch out: Needs an API shaped {data:[...]} that ends with an empty page. Adjust auth, Retry-After and cursors to the service contract; fix credentials on 401/403

  • SQL parameters with native query folding

    c04_SQL · Connector

    Passes date parameters without concatenating SQL strings

    Watch out: Table dbo.Sales must exist. Check View Native Query / the server plan, because EnableFolding does not guarantee every step folds

  • SharePoint folder limited to one path

    c05_SharePoint · Connector

    Filters the folder before reading any binary

    Watch out: Use the site URL, not a sharing link, and end Folder Path with / so similar names do not match

  • PDF table extraction

    c06_PDF · Connector

    Checks which tables the reader found before choosing the data

    Watch out: A connector blueprint. Scanned PDFs need OCR first and the schema may change, so pick the Data that matches the table

  • OData entity

    c07_OData · Connector

    Connects to an entity and lets the connector handle OData paging

    Watch out: Point the URL at the entity you need and set credentials for the real system

  • HTML table from a live website

    c08_Web · Connector

    Keeps the DOM selector separate from the download

    Watch out: The selector is an example and must match the real site. A page rendered by JavaScript may have no data in the downloaded HTML

Not yet available for download

The workbooks and guides are finished, and the distribution terms are being settled. Until then, every recipe is free to read on this site, with its result and its pitfalls.

Every report's Excel workbook is free to download, in Thai and English.