DEV Community

Cover image for SQL PATTERNS : Pivot and Unpivot in SQL - Transforming Data Effectively
Anwar
Anwar

Posted on

1 1

SQL PATTERNS : Pivot and Unpivot in SQL - Transforming Data Effectively

πŸ“Œ Introduction

Handling data transformations is a crucial skill in SQL, especially for reporting and analytics. PIVOT and UNPIVOT operations help in restructuring data efficiently:

πŸ”Ή PIVOT: Converts row-based data into a column-based format.
πŸ”Ή UNPIVOT: Converts column-based data into row-based format.

In this article, we will explore both operations with real-world examples.

πŸ›  Understanding PIVOT in SQL

Scenario: You have sales data in a normalized format where each row represents sales for a specific month. You want to convert this into a columnar format to generate reports.

πŸ“Œ Example: PIVOT Sales Data by Month

πŸ“Š Sample Table: Sales

Product Month Sales
Laptop Jan 5000
Laptop Feb 7000
Laptop Mar 8000
Phone Jan 3000
Phone Feb 4500
Phone Mar 5000

πŸ” PIVOT Query

SELECT * 
FROM (
    SELECT Product, Month, Sales
    FROM Sales
) AS SourceTable
PIVOT (
    SUM(Sales) 
    FOR Month IN ([Jan], [Feb], [Mar])
) AS PivotTable;
Enter fullscreen mode Exit fullscreen mode

βœ… Output

Product Jan Feb Mar
Laptop 5000 7000 8000
Phone 3000 4500 5000

🧐 Explanation

  • We used SUM(Sales) to aggregate values.
  • The FOR Month IN ([Jan], [Feb], [Mar]) clause dynamically transforms row values into column headers.

πŸ”„ Understanding UNPIVOT in SQL

Scenario: You receive a dataset where sales are already pivoted by months, but you need to transform it back into a normalized row-based format.

πŸ“Œ Example: UNPIVOT Sales Data

πŸ“Š Pivoted Table: Sales_Pivoted

Product Jan Feb Mar
Laptop 5000 7000 8000
Phone 3000 4500 5000

πŸ” UNPIVOT Query

SELECT Product, Month, Sales
FROM (
    SELECT Product, Jan, Feb, Mar
    FROM Sales_Pivoted
) AS PivotTable
UNPIVOT (
    Sales FOR Month IN (Jan, Feb, Mar)
) AS UnpivotTable;
Enter fullscreen mode Exit fullscreen mode

βœ… Output

Product Month Sales
Laptop Jan 5000
Laptop Feb 7000
Laptop Mar 8000
Phone Jan 3000
Phone Feb 4500
Phone Mar 5000

🧐 Explanation

The UNPIVOT operator converts multiple column values (Jan, Feb, Mar) back into row values under the Month column.
This makes it easier to analyze or join with other normalized tables.

πŸ“Œ When to Use PIVOT and UNPIVOT?

Use Case Operation
Convert rows into columns (e.g., monthly reports) PIVOT
Convert columns into rows (e.g., normalizing data) UNPIVOT

πŸš€ Conclusion

PIVOT and UNPIVOT are powerful SQL techniques that help in data transformation for better reporting and analysis. Mastering them will enable you to handle structured data more effectively.

πŸ’‘ What are your thoughts?

Have you used PIVOT and UNPIVOT in your SQL queries? Let’s discuss in the comments! ⬇️

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (2)

Collapse
 
aaronre16397861 profile image
Aaron Reese β€’

The main frustration with PIVOT and UNPIVOT is you need to know the values in the column that you want to effect the command on. In your example you have effected on Month which is a known limited list. If you wanted to effect on Product this lost could change over time. The only way to solve this is to create a dynamic query: use a concatenation technique (STR_AGG or STUFF...FOR XML) to generate a list of values and then build the SQL statement into a variable which you can then call with EXEC sp_executeSql @sql

PIVOTed data is not usable in a view because the column data is not fixed.

Collapse
 
anwaar profile image
Anwar β€’ β€’ Edited

You're absolutely right! The main challenge with PIVOT and UNPIVOT is that they require a fixed set of column values, making them less flexible for dynamic datasets where values change over time (e.g., Product names).

To handle this dynamically,

  1. One approach as you said would be a concatenation technique (STR_AGG or STUFF...FOR XML)
  2. Instead of pivoting dynamically at runtime, a Materialized View or Scheduled Job can precompute pivoted data and store it in a table.

Takeaways
βœ… Static PIVOTs work best with known, limited values (e.g., Months).
βœ… For dynamic data (e.g., Products, dynamic categories), use dynamic SQL with STRING_AGG or STUFF...FOR XML.
βœ… Views do not support dynamic PIVOTs, but Stored Procedures provide a flexible alternative.

Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • --last-failed: Zero in on just the tests that failed in your previous run
  • --only-changed: Test only the spec files you've modified in git
  • --repeat-each: Run tests multiple times to catch flaky behavior before it reaches production
  • --forbid-only: Prevent accidental test.only commits from breaking your CI pipeline
  • --ui --headed --workers 1: Debug visually with browser windows and sequential test execution

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Practical examples included!

Watch Video πŸ“ΉοΈ

πŸ‘‹ Kindness is contagious

DEV is better (more customized, reading settings like dark mode etc) when you're signed in!

Okay