sqlintermediate
SQL Pivot and Crosstab Queries
Transform row data into columnar reports using CASE expressions, FILTER, and crosstab patterns.
sqlPress ⌘/Ctrl + Shift + C to copy
-- Pivot with CASE expressions (works in all databases)
SELECT
product,
SUM(CASE WHEN month = 'Jan' THEN revenue ELSE 0 END) AS jan,
SUM(CASE WHEN month = 'Feb' THEN revenue ELSE 0 END) AS feb,
SUM(CASE WHEN month = 'Mar' THEN revenue ELSE 0 END) AS mar,
SUM(revenue) AS total
FROM monthly_sales
GROUP BY product
ORDER BY total DESC;
-- Pivot with FILTER clause (PostgreSQL)
SELECT
region,
COUNT(*) FILTER (WHERE status = 'active') AS active,
COUNT(*) FILTER (WHERE status = 'inactive') AS inactive,
COUNT(*) FILTER (WHERE status = 'pending') AS pending,
COUNT(*) AS total
FROM users
GROUP BY region;
-- Unpivot (turn columns into rows)
SELECT product, 'Jan' AS month, jan AS revenue FROM pivot_table
UNION ALL
SELECT product, 'Feb', feb FROM pivot_table
UNION ALL
SELECT product, 'Mar', mar FROM pivot_table
ORDER BY product, month;
-- Dynamic-style pivot with JSON aggregation
SELECT
user_id,
jsonb_object_agg(setting_key, setting_value) AS settings
FROM user_settings
GROUP BY user_id;
-- Cross-tabulation: users per role per department
SELECT
department,
COUNT(*) FILTER (WHERE role = 'engineer') AS engineers,
COUNT(*) FILTER (WHERE role = 'designer') AS designers,
COUNT(*) FILTER (WHERE role = 'manager') AS managers
FROM employees
GROUP BY department
ORDER BY department;Use Cases
- Creating monthly revenue reports
- User segmentation cross-tabulations
- Transforming EAV data into tabular format
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
sqlintermediate
Pivot - Technique 44
Pivot row values into columns
Best for: database operations
#sql#database
sqladvanced
SQL Window Functions for Analytics
Advanced SQL window functions for running totals, rankings, moving averages, and gap analysis.
Best for: Building analytics dashboards with running totals
#sql#window-functions
sqlbeginner
String Aggregation with GROUP BY
Concatenate grouped values into comma-separated strings using STRING_AGG with ordering and filtering.
Best for: Tag lists per item
#aggregation#string-agg
sqlbeginner
Generate Series Calendar Table
Create a date calendar using generate_series for gap-free time series reporting and joins.
Best for: Daily revenue reports
#generate-series#calendar