Table.AlternateRows

Table

Keeps an initial number of rows, then alternates between skipping and keeping groups of rows.

Examples on this page use shared sample tables. View them to understand the input data before reading the examples below.

Syntax

Table.AlternateRows(table as table, offset as number, skip as number, take as number) as table

Parameters

NameTypeRequiredDescription
tabletableYesThe table to process.
offsetnumberYesThe number of rows at the start of the table to keep before the skip/take pattern begins.
skipnumberYesThe number of consecutive rows to remove in each cycle.
takenumberYesThe number of consecutive rows to keep after each skipped group.

Return Value

table — A table containing the first offset rows plus the rows kept by the skip/take pattern.

Remarks

Table.AlternateRows first keeps the first offset rows unconditionally. After that it repeats a skip-then-take cycle until the end of the table: it removes the next skip rows, then keeps the next take rows. Note the order: each cycle skips first, so Table.AlternateRows(t, 0, 1, 1) keeps the 2nd, 4th, 6th… rows, while Table.AlternateRows(t, 1, 1, 1) keeps the 1st, 3rd, 5th… rows.

This function is primarily useful when consuming data that has a fixed repeating structure — for example, raw exports where every second row is a separator, or flat files where every Nth row contains a record header that should be discarded after parsing. For purely row-count-based skipping or selection, Table.Skip and Table.FirstN are simpler alternatives.

Be aware that Table.AlternateRows does not typically fold to the data source, so it will be evaluated locally. For large datasets, consider pre-filtering at the source before applying this function.

Examples

Example 1: Sample every other row (keep 1, drop 1)

let
    Source = #table(
        {"OrderID", "CustomerName", "Product"},
        {
            {1, "Alice",   "Widget A"},
            {2, "Bob",     "Gadget B"},
            {3, "Charlie", "Widget C"},
            {4, "Alice",   "Gadget D"},
            {5, "Diana",   "Widget A"},
            {6, "Bob",     "Thingamajig E"},
            {7, "Charlie", "Gadget B"},
            {8, "Diana",   "Widget C"}
        }
    )
in
    Table.AlternateRows(Source, 1, 1, 1)
Applied Steps

The final output — Table.AlternateRows keeps the first row (offset 1), then repeatedly skips 1 row and keeps 1 row, so orders 1, 3, 5, and 7 remain.

OrderID
CustomerName
Product
11AliceWidget A
23CharlieWidget C
35DianaWidget A
47CharlieGadget B

Example 2: Drop every third row (a repeating divider)

Table.AlternateRows(
    #table({"Row"}, {{"A"}, {"B"}, {"SEP"}, {"C"}, {"D"}, {"SEP"}, {"E"}, {"F"}}),
    2, 1, 2
)
Output
Row
1A
2B
3C
4D
5E
6F

Example 3: Use offset to preserve a header before the pattern starts

Table.AlternateRows(
    #table({"Row"}, {{"Header"}, {"SEP"}, {"Data1"}, {"SEP"}, {"Data2"}}),
    1, 1, 1
)
Output
Row
1Header
2Data1
3Data2

Compatibility

✓ Power BI Desktop✓ Power BI Service✓ Excel Desktop✓ Excel Online✓ Dataflows✓ Fabric Notebooks
Contributors
kyleamueller