Category: Data Transformation
Platform Support:
✅ Snowflake (PIVOT) | ✅ BigQuery (PIVOT/UNPIVOT) | ✅ Databricks (PIVOT)
Description
PIVOT transforms rows into columns (wide format), while UNPIVOT transforms columns into rows (long format). Essential for reshaping data for analysis, reporting, and converting between normalized and denormalized formats.
Syntax
PIVOT:
UNPIVOT:
Platform-Specific Notes
Snowflake:
Full PIVOT support
Dynamic PIVOT with variables
UNPIVOT support
Can pivot on multiple columns
BigQuery:
PIVOT and UNPIVOT supported
Requires explicit column list in PIVOT
String aggregation works well with PIVOT
UNPIVOT for converting wide to long
Databricks:
PIVOT supported (Spark SQL)
Can use expressions in pivot values
UNPIVOT via STACK or melt operations
Dynamic pivoting with SQL generation
Example 1: PIVOT - Sales by Month
All Platforms:
Sample Data (sales_data - long format):
product_name | month | sales |
|---|---|---|
Laptop | Jan | 10000 |
Laptop | Feb | 12000 |
Laptop | Mar | 11000 |
Mouse | Jan | 500 |
Mouse | Feb | 600 |
Mouse | Mar | 550 |
Result (wide format):
product_name | Jan | Feb | Mar | Apr | May | Jun |
|---|---|---|---|---|---|---|
Laptop | 10000 | 12000 | 11000 | NULL | NULL | NULL |
Mouse | 500 | 600 | 550 | NULL | NULL | NULL |
Example 2: PIVOT - Multiple Aggregations
Snowflake/Databricks:
BigQuery:
Sample Data:
region | product_category | revenue | units_sold |
|---|---|---|---|
East | Electronics | 50000 | 150 |
West | Electronics | 60000 | 180 |
East | Furniture | 30000 | 75 |
West | Furniture | 35000 | 90 |
Result:
product_category | East_total_revenue | East_total_units | West_total_revenue | West_total_units | ... |
|---|---|---|---|---|---|
Electronics | 50000 | 150 | 60000 | 180 | ... |
Furniture | 30000 | 75 | 35000 | 90 | ... |
Example 3: UNPIVOT - Convert Wide to Long
Snowflake:
BigQuery:
Databricks (using STACK):
Sample Data (monthly_sales - wide format):
product_name | jan | feb | mar | apr | may | jun |
|---|---|---|---|---|---|---|
Laptop | 10000 | 12000 | 11000 | NULL | NULL | NULL |
Mouse | 500 | 600 | 550 | NULL | NULL | NULL |
Result (long format):
product_name | month | sales |
|---|---|---|
Laptop | jan | 10000 |
Laptop | feb | 12000 |
Laptop | mar | 11000 |
Mouse | jan | 500 |
Mouse | feb | 600 |
Mouse | mar | 550 |
Example 4: Dynamic PIVOT (Snowflake)
Snowflake:
Example 5: PIVOT for Cross-Tabulation
All Platforms:
Sample Data:
customer_id | age_group | income_level |
|---|---|---|
1 | 18-25 | Low |
2 | 18-25 | Medium |
3 | 18-25 | Low |
4 | 26-35 | High |
5 | 26-35 | Medium |
6 | 36-50 | Very High |
Result:
age_group | Low | Medium | High | Very High |
|---|---|---|---|---|
18-25 | 2 | 1 | 0 | 0 |
26-35 | 0 | 1 | 1 | 0 |
36-50 | 0 | 0 | 0 | 1 |
Example 6: PIVOT with Conditional Aggregation Alternative
All Platforms (without PIVOT):
This produces the same result as PIVOT but is more verbose
PIVOT vs Manual Aggregation
Aspect | PIVOT | CASE WHEN |
|---|---|---|
Readability | High | Medium |
Dynamic columns | Harder | Harder |
Performance | Optimized | Similar |
Flexibility | Limited | High |
Syntax | Cleaner | Verbose |
Common Use Cases
PIVOT:
Time-series analysis: Sales by month, year
Cross-tabulation: Demographics vs behavior
Reporting: Convert transactional to summary format
Dashboards: Prepare data for visualization
Comparison: Side-by-side metrics
UNPIVOT:
Normalization: Convert wide tables to long
Data import: Flatten spreadsheet data
Time-series: Monthly columns to date rows
Analytics: Prepare data for aggregation
ETL: Transform legacy formats
Performance Considerations
PIVOT can be memory-intensive with many columns
UNPIVOT is generally efficient
Consider materialized views for frequent pivots
Index base columns before pivoting
Limit pivot columns when possible
Best Practices
Know your pivot values: List all expected values
Handle NULLs: Use COALESCE or IFNULL for missing data
Limit columns: Too many pivot columns hurt readability
Document transformations: Explain pivot logic
Consider alternatives: CASE WHEN for simple pivots
Test with real data: Verify all expected values appear
Use aliases: Make column names readable





