Skip to main content

Pipe Syntax

Write and convert BigQuery pipe syntax — a linear, top-to-bottom way to compose SQL using the |> operator.

Pipe Syntax Example

What is Pipe Syntax?

A data-flow oriented way to write SQL where each step feeds into the next using the |> operator. Unlike standard SQL, pipe syntax reads in execution order — top to bottom.

Standard SQL:

SELECT user_id, COUNT(*) AS orders
FROM orders
WHERE status = 'completed'
GROUP BY user_id
ORDER BY orders DESC;

Pipe Syntax:

FROM orders
|> WHERE status = 'completed'
|> AGGREGATE COUNT(*) AS orders GROUP BY user_id
|> ORDER BY orders DESC;

Operator Reference

All 21 BigQuery pipe operators:

Standard SQLPipe Syntax
SELECT cols FROM tableFROM table |> SELECT cols
WHERE condition|> WHERE condition
GROUP BY cols + aggregates|> AGGREGATE ... GROUP BY cols
HAVING condition|> WHERE condition (after AGGREGATE)
SELECT DISTINCT *|> DISTINCT
JOIN table ON ...|> JOIN table ON ...
ORDER BY cols|> ORDER BY cols
LIMIT n|> LIMIT n
(no equivalent)|> EXTEND expr AS alias
(no equivalent)|> SET col = expr
(no equivalent)|> DROP col1, col2
(no equivalent)|> RENAME old AS new
AS alias|> AS alias
WITH cte AS (...)|> WITH cte AS (...)
TABLESAMPLE SYSTEM (n PERCENT)|> TABLESAMPLE SYSTEM (n PERCENT)
PIVOT(agg FOR col IN (...))|> PIVOT(agg FOR col IN (...))
UNPIVOT(val FOR name IN (...))|> UNPIVOT(val FOR name IN (...))
ML.PREDICT(MODEL m, TABLE t)FROM t |> CALL ML.PREDICT(MODEL m)
UNION ALL|> UNION ALL (...)
INTERSECT DISTINCT|> INTERSECT DISTINCT (...)
EXCEPT DISTINCT|> EXCEPT DISTINCT (...)
MATCH_RECOGNIZE(...)|> MATCH_RECOGNIZE(...)

Pipe-Only Operators

These operators only exist in pipe syntax — no standard SQL equivalent.

EXTEND

Add computed columns without listing all existing columns:

FROM users
|> EXTEND UPPER(name) AS name_upper;

Keeps all columns and adds name_upper.

SET, DROP, RENAME

Modify columns in place without rewriting the full SELECT list:

FROM users
|> SET name = UPPER(name)
|> DROP password, salt
|> RENAME email AS contact_email;

DISTINCT

Remove duplicate rows while preserving table aliases:

FROM users
|> DISTINCT
|> WHERE age > 18;

AGGREGATE

Replace GROUP BY + SELECT with a single operator. Grouping columns are listed once and automatically included in output:

FROM orders
|> AGGREGATE
SUM(amount) AS total,
COUNT(*) AS cnt
GROUP BY region;

No need to repeat region in a SELECT — it's included automatically. Supports ROLLUP, CUBE, GROUPING SETS, and an inline GROUP AND ORDER BY shorthand that combines grouping and sorting:

-- GROUP AND ORDER BY groups and sorts in one step
FROM orders
|> AGGREGATE SUM(amount) AS total
GROUP AND ORDER BY customer_id;

This is equivalent to GROUP BY customer_id |> ORDER BY customer_id — useful when you want results sorted by the grouping key.


Advanced Operators

WITH (Scoped CTEs)

Define common table expressions mid-pipeline:

FROM orders
|> WHERE status = 'completed'
|> WITH regional AS (
FROM regions |> SELECT id, name
)
|> JOIN regional ON orders.region_id = regional.id
|> SELECT regional.name, orders.amount;

Pipe WITH passes the input table through unchanged and makes the CTE available to subsequent operations.

Set Operations

UNION, INTERSECT, and EXCEPT are fully supported in pipe syntax:

-- Standard SQL
SELECT id FROM users UNION ALL SELECT id FROM admins

-- Pipe Syntax
FROM users
|> SELECT id
|> UNION ALL (FROM admins |> SELECT id)

BY NAME modifier — match columns by name instead of position. Useful when the two queries return the same columns in different order:

FROM table1
|> UNION ALL BY NAME (SELECT * FROM table2)

-- Also works with INTERSECT and EXCEPT
FROM table1
|> EXCEPT DISTINCT BY NAME (SELECT * FROM table2)

Without BY NAME, columns are matched by position and names are ignored.

Multiple arguments — pass multiple queries to a single set operator without repeating the keyword:

FROM table1
|> UNION ALL
(SELECT * FROM table2),
(SELECT * FROM table3)

PIVOT and UNPIVOT

Transform rows to columns and vice versa:

-- PIVOT: Rows to columns
FROM sales
|> PIVOT(SUM(revenue) FOR quarter IN ('Q1', 'Q2', 'Q3', 'Q4'))

-- UNPIVOT: Columns to rows
FROM quarterly_data
|> UNPIVOT(revenue FOR quarter IN (Q1, Q2, Q3, Q4))

UNPIVOT supports INCLUDE NULLS and EXCLUDE NULLS modifiers.

TABLESAMPLE

Sample data for faster exploration or cost reduction:

FROM large_table
|> TABLESAMPLE SYSTEM (10 PERCENT)
|> SELECT *

BigQuery pipe TABLESAMPLE uses the SYSTEM method with a percentage.

CALL (Table-Valued Functions)

Call table-valued functions (TVFs) including BigQuery ML:

-- Pipe syntax
FROM input_data
|> CALL ML.PREDICT(MODEL `project.dataset.model`)

-- Equivalent standard SQL
SELECT * FROM ML.PREDICT(MODEL `project.dataset.model`, TABLE(input_data))

Works with ML.PREDICT, ML.GENERATE_TEXT, ML.FORECAST, and custom TVFs.

MATCH_RECOGNIZE

Find sequences of rows that match a pattern — similar to regular expressions, but applied to rows instead of characters:

FROM stock_prices
|> MATCH_RECOGNIZE(
PARTITION BY ticker
ORDER BY trade_date
MEASURES
FIRST(price) AS start_price,
LAST(price) AS end_price
PATTERN (dip+ rise+)
DEFINE
dip AS price < PREV(price),
rise AS price > PREV(price)
)

PARTITION BY groups rows before matching. MEASURES defines what to output for each match. PATTERN uses quantifiers like + and *. DEFINE specifies what each symbol means in terms of row conditions.


Mixed Syntax

BigQuery supports mixing standard and pipe syntax in the same query.

WITH cleaned AS (
FROM raw_events
|> WHERE event_date >= '2024-01-01'
|> SELECT user_id, event_type
),
stats AS (
SELECT user_id, COUNT(*) AS count
FROM cleaned
GROUP BY user_id
)
SELECT * FROM stats;

Conversion & Tooling

Keyboard Shortcuts

ActionMacWindows/Linux
Convert to PipeCmd+Alt+PCtrl+Alt+P
Convert to StandardCmd+Alt+SCtrl+Alt+S

Works on full document or selection.

Convert to Pipe Menu Convert from Pipe Menu

Debugging with Partial Execution

Pipe syntax works with Partial Execution — each |> shows a gutter icon. Shift+Click any pipe operator to execute up to that stage and inspect intermediate results.

Pipe Stage Navigation

Online Converter

Try our free Pipe Syntax Converter — no login required. Convert between standard SQL and pipe syntax right in the browser with full syntax highlighting and formatting.


Limitations

  • SELECT without FROM cannot convert to pipe (pipe requires FROM)
  • Use partial conversion (select portion, then convert) for complex queries