Pivot with "Others" Column

QuestDB has a native PIVOT keyword for transforming rows into columns. However, when you need to pivot specific values while grouping all remaining values into an "Others" column, you need to use CASE statements instead.

Problem

You want to pivot data so that specific symbols (like EURUSD, GBPUSD, USDJPY) become columns, but also capture all other symbols in a single "Others" column:

Aggregated data per symbolDemo this query
SELECT timestamp, symbol, SUM(bid_volume) AS total_bid
FROM core_price
WHERE timestamp IN today()
SAMPLE BY 1m
LIMIT 20;

Results:

timestampsymboltotal_bid
2026-01-11T00:00:00.000000ZEURGBP124820733
2026-01-11T00:00:00.000000ZAUDUSD124778371
2026-01-11T00:00:00.000000ZGBPAUD124645353
2026-01-11T00:00:00.000000ZGBPNZD129175334
2026-01-11T00:00:00.000000ZNZDUSD127053437
2026-01-11T00:00:00.000000ZUSDSGD130915407
2026-01-11T00:00:00.000000ZUSDJPY123039292
2026-01-11T00:00:00.000000ZAUDCAD121234190
2026-01-11T00:00:00.000000ZUSDMXN122254886
2026-01-11T00:00:00.000000ZUSDSEK129272298
2026-01-11T00:00:00.000000ZUSDNOK124493591
2026-01-11T00:00:00.000000ZEURJPY126254805
2026-01-11T00:00:00.000000ZCADJPY133359111
2026-01-11T00:00:00.000000ZEURCHF125818826
2026-01-11T00:00:00.000000ZGBPJPY130940614
2026-01-11T00:00:00.000000ZUSDCAD126619566
2026-01-11T00:00:00.000000ZUSDTRY124860359
2026-01-11T00:00:00.000000ZAUDJPY135946504
2026-01-11T00:00:00.000000ZNZDJPY126419110
2026-01-11T00:00:00.000000ZEURAUD122966167

Solution

Use CASE statements with NOT IN for the "Others" column:

Pivot with Others columnDemo this query
SELECT timestamp,
SUM(CASE WHEN symbol = 'EURUSD' THEN bid_volume END) AS EURUSD,
SUM(CASE WHEN symbol = 'GBPUSD' THEN bid_volume END) AS GBPUSD,
SUM(CASE WHEN symbol = 'USDJPY' THEN bid_volume END) AS USDJPY,
SUM(CASE WHEN symbol NOT IN ('EURUSD', 'GBPUSD', 'USDJPY')
THEN bid_volume END) AS OTHERS
FROM core_price
WHERE timestamp IN today()
SAMPLE BY 1m
LIMIT 5;

Results:

timestampEURUSDGBPUSDUSDJPYOTHERS
2026-01-11T00:00:00.000000Z1237171751232523881230392922755547557
2026-01-11T00:01:00.000000Z1309477361365095651270068582877498962
2026-01-11T00:02:00.000000Z1300044901258046601224514772824893498
2026-01-11T00:03:00.000000Z1243032441265890461244356382797775211
2026-01-11T00:04:00.000000Z1207436691279913521229701852733242883

Each timestamp now has a single row with specific symbols as columns, plus an "Others" column aggregating all remaining symbols.

When to Use This Pattern

Use CASE statements instead of PIVOT when you need:

  • An "Others" or "Else" column to catch unspecified values
  • Custom aggregation logic per column
  • Different aggregation functions for different columns

For straightforward pivoting without an "Others" column, use the native PIVOT keyword.