SQL Playground
TutorialsPlayground
SQL FormatterSQL MinifierSyntax ValidatorJSON to SQLCSV to SQLSQL to JSONER Diagram Generator
Daily ChallengeInterviewsCheat SheetBlog

© 2026 SQL Playground. Built for developers.

PrivacyTermsAboutRSS Feed
SQL Playground
TutorialsPlayground
SQL FormatterSQL MinifierSyntax ValidatorJSON to SQLCSV to SQLSQL to JSONER Diagram Generator
Daily ChallengeInterviewsCheat SheetBlog
Back to Blog
2025-12-26
4 min read

How to Create Pivot Tables in SQL (Without the PIVOT Operator)

sqltutorialpivot-tablesreportingdata-analysis

Have you ever looked at a long list of transaction data and thought, "I wish I could see this as a grid?"

Instead of scrolling through thousands of rows like this:

MonthCategorySales
JanElectronics500
JanClothing300
FebElectronics600
FebClothing400

You often want a Pivot Table (or Cross-Tabulation) that looks like this:

CategoryJan SalesFeb Sales
Electronics500600
Clothing300400

While some databases (like SQL Server or Oracle) have a dedicated PIVOT operator, standard SQL offers a more universal, flexible way to do this using Conditional Aggregation.

The Secret Sauce: Conditional Aggregation

The technique relies on combining SUM() (or COUNT()) with CASE WHEN.

Think of it like this:

  1. Group by the row labels (e.g., Category).
  2. Create a column for each value you want to pivot (e.g., Jan, Feb).
  3. Filter data inside the aggregation function so only the relevant data for that column is summed.
SELECT 
  category,
  SUM(CASE WHEN month = 'Jan' THEN sales ELSE 0 END) as jan_sales,
  SUM(CASE WHEN month = 'Feb' THEN sales ELSE 0 END) as feb_sales
FROM result_table
GROUP BY category;

Step-by-Step Example

Let's dive into a real example using a monthly_sales table.

1. The Rough Data

First, let's look at our raw data. We have sales data for different product categories across different months.

Interactive SQL
Loading...

2. Pivoting Months to Columns

Refining the report to show one row per category, with months as columns.

Interactive SQL
Loading...

Analysis:

  • We GROUP BY category to ensure each category gets exactly one row.
  • Inside SUM(), the CASE statement checks the month. If it matches, it adds the revenue; if not, it adds 0.
  • We also added a total_q1_revenue column by simply summing everything without a condition!

Advanced: Dynamic Pivots?

A common question is: "What if I don't know the months beforehand? Can I make it dynamic?"

In standard SQL: No. You must know your columns when writing the query. To achieve dynamic columns (e.g., if new months appear automatically), you usually naturally need to use a stored procedure or build the query string dynamically in your application code (Python, Node.js, etc.) before sending it to the database.

Handling NULLs vs Zeros

Sometimes ELSE 0 isn't what you want. If a product had no sales record at all, SUM returns NULL by default if you don't provide an ELSE.

  • Use ELSE 0 if you want to perform math (like row totals).
  • Omit ELSE (or use ELSE NULL) if you want to distinguishing between "Zero Sales" and "No Data".

Comparing Approaches

FeatureStandard PIVOT (Oracle/SQL Server)Conditional Aggregation (Standard SQL)
SyntaxConcise specific syntaxVerbose but explicit
PortabilityLow (Vendor specific)High (Works everywhere: MySQL, Postgres, SQLite)
flexibilityLimited to aggregationHighly flexible (can pivot multiple metrics)

Practice Challenge

Try modifying the query above to:

  1. Pivot the data so Months are rows and Categories are columns (flip the axes!).
  2. Calculate the average revenue instead of total revenue.

Conclusion

Manual pivoting with SUM(CASE WHEN...) is a fundamental skill for SQL reporting. It turns vertical data, which computers love, into horizontal data, which humans love to read. While it requires writing a bit more code, its flexibility and universal support make it the preferred method for data analysts.

Share this article:

Comments

© 2026 SQL Playground. Built for developers.

PrivacyTermsAboutRSS Feed