feat(sql): support PIVOT keyword for rotating rows to columns#5313
Merged
bluestreak01 merged 25 commits intomasterfrom Jan 6, 2026
Merged
feat(sql): support PIVOT keyword for rotating rows to columns#5313bluestreak01 merged 25 commits intomasterfrom
PIVOT keyword for rotating rows to columns#5313bluestreak01 merged 25 commits intomasterfrom
Conversation
PIVOT keyword for pivoting rows into columnsPIVOT and UNPIVOT keywords for rotating tables
Member
Member
Member
Member
bluestreak01
reviewed
May 2, 2025
Member
|
50% of the code in the new factory is untested |
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
Member
Member
Member
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
bluestreak01
reviewed
May 2, 2025
Collaborator
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
bluestreak01
reviewed
Jan 5, 2026
bluestreak01
reviewed
Jan 5, 2026
Contributor
[PR Coverage check]😍 pass : 741 / 815 (90.92%) file detail
|
bluestreak01
reviewed
Jan 6, 2026
Member
|
this sql should error out (trades limit 100000)0
pivot (
first(price), last(price)
for symbol in ('sym1', 'sym2')
); |
Collaborator
It is actually meaningful here. It’s worth noting that DuckDB also supports similar syntax. |
bluestreak01
approved these changes
Jan 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.







Preamble
Fixes #997
Depends on #5435
Depends on #5408
Summary
This PR introduces the new
PIVOTkeyword.In simple terms,
PIVOTis a specialisedGROUP BYquery, that helps to group up a selection of rows into columns - essentially, pivoting from a narrow schema, to a wide schema.Let's take our example trades table:
In this table, we have some crypto trading data.
Let's say we wanted to get the latest buy and sell prices for some tickers. We could write a group by query:
Which gives:
But what if we want to have a wide schema, with a column per symbol?
PIVOTsolves this problem, by performing a combined filter plus aggregation on rows, and mapping the values to columns.For example:
This query performs a similar
GROUP BYto the first query, aGROUP BY side, symbolwith appropriate filtering. Then, a second aggregation is performed, along with per-column filtering usingCASEexpressions, to create the final columns.Here is the result:
We can now compare the plans for the two queries.
Original query:
PIVOT query:
Observe that the first part of the query, the
Async JIT Group Byis in fact, identical, for both queries. Only the final step changes, wherein thePIVOTquery additionally pivots the data.What about
UNPIVOT? Not allPIVOTqueries are reversible, butUNPIVOTcan reverse simple ones. For example:( trades PIVOT ( last(price) FOR symbol IN ('BTC-USD', 'ETH-USD') GROUP BY side ) ) UNPIVOT ( price FOR symbol IN ('BTC-USD', 'ETH-USD') );gives:
Changelist:
Required
SAMPLE BY-> supported using a subquerySupport SQL Standard UNPIVOT syntaxnow in feat(sql): supportUNPIVOTkeyword for rotating columns to rows #5732Desirable/future work
FORtitle i.eFOR abc IN ('a', 'b', 'c') as defFOR foo IN ('bah' as baz)INlist i.eFOR foo IN (select some_string FROM table)ELSEexpression, to capture all rows not included in theFORfilter:FOR foo IN (bah) ELSE 'baz'BTC-USDtrades occurred compared to all other trades.FOR foo NOT IN (bah)Extended UNPIVOTnow in feat(sql): supportUNPIVOTkeyword for rotating columns to rows #5732