Sql Server Pivoting And Unpivoting Data Complete Guide

 Last Update:2025-06-23T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    9 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of SQL Server Pivoting and Unpivoting Data

SQL Server Pivoting and Unpivoting Data

Introduction

Pivoting Data

Pivoting rotates a table-valued expression by turning the unique values from one column into multiple columns in the output, and performs aggregations where required on any remaining column values. The general syntax for pivoting in SQL Server is:

SELECT 
    non-pivoted_column,
    [pivoted_column_value1] AS alias_1,
    [pivoted_column_value2] AS alias_2,
    ...
FROM 
    (SELECT 
         non-pivoted_column,
         pivoted_column,
         value_column
     FROM 
         table_name) AS source_table
PIVOT
(
    aggregation_function (value_column)
    FOR pivoted_column
    IN ([pivoted_column_value1], [pivoted_column_value2], ...)
) AS pivot_table;

Example:

Suppose you have a table Sales with the following structure:

| CustomerID | Product | SalesAmount | |------------|-----------|-------------| | 1 | Product1 | 100 | | 1 | Product2 | 200 | | 2 | Product1 | 150 | | 2 | Product2 | 250 |

You can pivot this data to show totals for each product:

SELECT 
    CustomerID,
    Product1,
    Product2
FROM 
    (SELECT 
         CustomerID,
         Product,
         SalesAmount
     FROM 
         Sales) AS SourceTable
PIVOT
(
    SUM(SalesAmount)
    FOR Product
    IN (Product1, Product2)
) AS PivotTable;

Result:

| CustomerID | Product1 | Product2 | |------------|----------|----------| | 1 | 100 | 200 | | 2 | 150 | 250 |

Unpivoting Data

Unpivoting is the reverse of pivoting, converting a 'wide' format table into a 'long' format table. This is useful when you have columns that represent categories and you want to turn them into values in a single column. The general syntax for unpivoting in SQL Server is:

SELECT 
    non-unpivoted_column,
    category_column,
    value_column
FROM 
    table_name
UNPIVOT
(
    value_column
    FOR category_column IN ([column1], [column2], ...)
) AS unpivot_table;

Example:

Continuing with the previous pivoted data, if you want to convert it back to the original format:

SELECT 
    CustomerID,
    Product,
    SalesAmount
FROM 
    (SELECT 
         CustomerID,
         Product1,
         Product2
     FROM 
         PivotTable) AS SourceTable
UNPIVOT
(
    SalesAmount
    FOR Product IN (Product1, Product2)
) AS UnpivotTable;

Result:

| CustomerID | Product | SalesAmount | |------------|----------|-------------| | 1 | Product1 | 100 | | 1 | Product2 | 200 | | 2 | Product1 | 150 | | 2 | Product2 | 250 |

Key Points

  1. Pivoting: Converts rows to columns, often using aggregation functions.

    • Suitable for transforming data for reports or specific visualizations.
    • Requires careful selection of columns to pivot and aggregate.
  2. Unpivoting: Converts columns to rows.

    • Useful for normalizing data or preparing it for further transformations.
    • Simplifies complex datasets by breaking them down into simpler structures.
  3. Use Cases:

    • Data Analysis: Analyzing sales data across different products or regions.
    • Reporting: Preparing data for dashboards or reports that require specific column structures.
    • Data Transformation: Reshaping data for machine learning models or other analytical tools.
  4. Performance Considerations:

    • Pivoting and unpivoting can affect performance, especially on large datasets.
    • Indexes on the columns involved in pivoting can improve performance.
    • Consider the use of Common Table Expressions (CTEs) or subqueries to break down complex queries.

Conclusion

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement SQL Server Pivoting and Unpivoting Data

Example 1: Pivoting Data

Scenario: You have a table that stores the monthly sales of a company by product. You want to transform this table so that each product is represented as a column, making it easier to compare sales across different products.

Step 1: Create the Example Table

First, let's create a sample table named MonthlySales:

CREATE TABLE MonthlySales (
    ProductID INT,
    SaleMonth CHAR(3),
    SalesAmount DECIMAL(10,2)
);

INSERT INTO MonthlySales (ProductID, SaleMonth, SalesAmount) VALUES
(1, 'Jan', 450.00),
(1, 'Feb', 670.00),
(1, 'Mar', 380.00),
(2, 'Jan', 320.00),
(2, 'Feb', 540.00),
(2, 'Mar', 129.00);

The above script creates a MonthlySales table with three columns: ProductID, SaleMonth, and SalesAmount. It then inserts some example data.

Step 2: Pivot the Data

Now, let's use the PIVOT function to transform the sales data into columns:

SELECT 
    ProductID,
    Jan,
    Feb,
    Mar
FROM 
(
    SELECT 
        ProductID,
        SaleMonth,
        SalesAmount
    FROM 
        MonthlySales
) AS SourceTable
PIVOT
(
    SUM(SalesAmount)
    FOR SaleMonth IN ([Jan], [Feb], [Mar])
) AS PivotTable;

Explanation:

  • The inner SELECT statement (aliased as SourceTable) selects the ProductID, SaleMonth, and SalesAmount from the MonthlySales table.
  • The PIVOT statement transforms the SalesAmount rows into columns, where SaleMonth represents the column headers (Jan, Feb, Mar).
  • The SUM(SalesAmount) aggregates the sales amount for each month per product.

Output:

ProductID   Jan       Feb       Mar
----------- --------- --------- ---------
1           450.00    670.00    380.00
2           320.00    540.00    129.00

Example 2: Unpivoting Data

Scenario: Consider you have a table with sales data broken down by product and month stored as columns. You want to restructure this table back to a format where each row represents a product's sales for a specific month.

Step 1: Create the Example Table

Let's assume we have a new table ProductsByMonthSales which includes the pivoted data:

CREATE TABLE ProductsByMonthSales (
    ProductID INT,
    Jan DECIMAL(10,2),
    Feb DECIMAL(10,2),
    Mar DECIMAL(10,2)
);

INSERT INTO ProductsByMonthSales (ProductID, Jan, Feb, Mar) VALUES
(1, 450.00, 670.00, 380.00),
(2, 320.00, 540.00, 129.00);

Step 2: Unpivot the Data

Now, let's use the UNPIVOT function to transform this table back to the original structure (rows):

SELECT 
    ProductID,
    SaleMonth,
    SalesAmount
FROM 
(
    SELECT 
        ProductID,
        Jan,
        Feb,
        Mar
    FROM 
        ProductsByMonthSales
) AS SourceTable
UNPIVOT
(
    SalesAmount
    FOR SaleMonth IN (Jan, Feb, Mar)
) AS UnpivotTable;

Explanation:

  • The inner SELECT statement (aliased as SourceTable) selects all the columns representing the months of sales.
  • The UNPIVOT statement converts the columns back into rows, using FOR SaleMonth IN (Jan, Feb, Mar) to specify the columns to unpivot.
  • SalesAmount becomes the new value column for all unpivot operations.

Output:

ProductID   SaleMonth SalesAmount
----------- --------- -----------
1           Jan       450.00
1           Feb       670.00
1           Mar       380.00
2           Jan       320.00
2           Feb       540.00
2           Mar       129.00

Example 3: Dynamic Pivoting

If you don’t know in advance which months will be present in your data or if you have many months to pivot, you need to build a dynamic SQL query to handle this.

Step 1: Create the Example Table

Let’s stick with the same MonthlySales table created earlier.

Step 2: Generate the Dynamic Pivot Query

Dynamic pivoting requires building a SQL query string at runtime, based on the data. Here’s an example of how to do it:

DECLARE @DynamicPivotQuery NVARCHAR(MAX);
DECLARE @ColumnNameString NVARCHAR(MAX);

-- Get all distinct month names and prepare the column name string
SELECT @ColumnNameString = COALESCE(@ColumnNameString + ', [' + CAST(SaleMonth AS VARCHAR(10)) + ']','[' + CAST(SaleMonth AS VARCHAR(10)) + ']')
FROM (SELECT DISTINCT SaleMonth FROM MonthlySales) AS Months;

-- Construct the dynamic pivot query
SET @DynamicPivotQuery =
    N'SELECT ProductID, ' + @ColumnNameString +
    N' FROM MonthlySales ' +
    N'PIVOT (SUM(SalesAmount) FOR SaleMonth IN (' + @ColumnNameString + N')) AS PivotTable';

-- Execute the dynamic pivot query
EXEC sp_executesql @DynamicPivotQuery;

Explanation:

  • First, we retrieve all distinct sale months from the MonthlySales table and concatenate them into a single string (@ColumnNameString). This string is used in both the SELECT and FOR clauses of the PIVOT.
  • We construct the @DynamicPivotQuery string dynamically, substituting the concatenated column names.
  • Finally, we execute the constructed query using sp_executesql.

Example 4: Dynamic Unpivoting

To perform dynamic unpivoting, you also need to generate the SQL query at runtime.

Step 1: Create the Example Table

Again, let's use the ProductsByMonthSales table.

Step 2: Generate the Dynamic Unpivot Query

Here’s how to dynamically unpivot:

DECLARE @DynamicUnpivotQuery NVARCHAR(MAX);
DECLARE @ColumnNameString NVARCHAR(MAX);

-- Get all distinct month names and prepare the column name string
SELECT @ColumnNameString = COALESCE(@ColumnNameString + ', ' + QUOTENAME(COLUMN_NAME), QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'ProductsByMonthSales' AND COLUMN_NAME NOT IN ('ProductID');

-- Construct the dynamic unpivot query
SET @DynamicUnpivotQuery =
    N'SELECT ProductID, SaleMonth, SalesAmount ' +
    N'FROM ProductsByMonthSales ' +
    N'UNPIVOT (SalesAmount FOR SaleMonth IN (' + @ColumnNameString + N')) AS UnpivotTable';

-- Execute the dynamic unpivot query
EXEC sp_executesql @DynamicUnpivotQuery;

Explanation:

  • Using INFORMATION_SCHEMA.COLUMNS, we generate the list of month columns excluding ProductID.
  • We concatenate these column names into a single string (@ColumnNameString).
  • The @DynamicUnpivotQuery string is constructed to select the ProductID, dynamically generated column names representing SaleMonth, and SalesAmount in an unpivot operation.
  • The constructed query is executed using sp_executesql.

Top 10 Interview Questions & Answers on SQL Server Pivoting and Unpivoting Data

1. What are Pivoting and Unpivoting in SQL Server?

Answer: Pivoting and unpivoting are operations that allow you to reshape the format of a result set. Pivoting rotates a table-valued expression by turning the unique values of a specified column into column headers in the result set, and often involves aggregating remaining column values. Conversely, unpivoting rotates a table by turning the column headers into row values.

2. How do you perform a pivot operation in SQL Server?

Answer: To pivot data in SQL Server, you can use the PIVOT clause. Here’s a basic syntax example:

SELECT 
    Column1, 
    [Column2Value1], 
    [Column2Value2], 
    [Column2Value3]
FROM 
    TableName
PIVOT (
    AggregationFunction(Column3)
    FOR Column2 IN ([Column2Value1], [Column2Value2], [Column2Value3])
) AS PivotTableAlias;

Example: Suppose you have a table Sales with Product, Quarter, and SalesAmount columns. To pivot the Quarter column into individual columns:

SELECT 
    Product, 
    [Q1], [Q2], [Q3], [Q4]
FROM 
    Sales
PIVOT (
    SUM(SalesAmount)
    FOR Quarter IN ([Q1], [Q2], [Q3], [Q4])
) AS PivotTable;

3. How do you handle NULL values when pivoting in SQL Server?

Answer: When pivoting data, NULL values can occur if no data is available for a specific column after the pivot. You can handle NULL values using the ISNULL function in SQL Server.

Example:

SELECT 
    Product, 
    ISNULL([Q1], 0) AS Q1, 
    ISNULL([Q2], 0) AS Q2, 
    ISNULL([Q3], 0) AS Q3, 
    ISNULL([Q4], 0) AS Q4
FROM 
    Sales
PIVOT (
    SUM(SalesAmount)
    FOR Quarter IN ([Q1], [Q2], [Q3], [Q4])
) AS PivotTable;

4. What is unpivoting, and how do you perform it in SQL Server?

Answer: Unpivoting the data converts columns back into rows. This can be used to transform a wide table into a long format.

To unpivot, you can use the UNPIVOT clause. Here’s a basic syntax example:

SELECT 
    Column1, 
    NewColumn2Name, 
    NewColumn3Name
FROM 
    TableName
UNPIVOT (
    NewColumn3Name
    FOR NewColumn2Name IN ([Column2Value1], [Column2Value2], [Column2Value3])
) AS UnpivotTableAlias;

Example: Suppose you have a table where quarters are pivoted into columns:

SELECT 
    Product, Quarter, SalesAmount
FROM 
    PivotTable
UNPIVOT (
    SalesAmount
    FOR Quarter IN ([Q1], [Q2], [Q3], [Q4])
) AS UnpivotTable;

5. Can you dynamically pivot data in SQL Server?

Answer: Dynamic pivoting is useful when the column names that you want to pivot are not known beforehand. You can create a dynamic SQL query to handle this.

Example:

DECLARE @Columns NVARCHAR(MAX);
DECLARE @SQL NVARCHAR(MAX);

SELECT @Columns = 
  COALESCE(@Columns + N',', N'') + QUOTENAME(Quarter)
FROM (SELECT DISTINCT Quarter FROM Sales) AS T;

SET @SQL = 
N'SELECT Product, ' + @Columns + '
   FROM Sales
   PIVOT (
     SUM(SalesAmount)
     FOR Quarter IN (' + @Columns + ')
   ) AS PivotTable;';

EXEC sp_executesql @SQL;

6. How can you pivot data without using the PIVOT clause?

Answer: Without the PIVOT clause, you can achieve a similar result using conditional aggregation:

Example:

SELECT 
    Product,
    MAX(CASE WHEN Quarter = 'Q1' THEN SalesAmount ELSE 0 END) AS Q1,
    MAX(CASE WHEN Quarter = 'Q2' THEN SalesAmount ELSE 0 END) AS Q2,
    MAX(CASE WHEN Quarter = 'Q3' THEN SalesAmount ELSE 0 END) AS Q3,
    MAX(CASE WHEN Quarter = 'Q4' THEN SalesAmount ELSE 0 END) AS Q4
FROM 
    Sales
GROUP BY 
    Product;

7. What are some common use cases for SQL Server Pivoting?

Answer:

  • Report Generation: Creating reports that summarize data in a readable format.
  • Data Analysis: Analyzing data by rotating columns and rows for better insights.
  • Data Transformation: Converting wide tables into long tables or vice versa.
  • Normalization and Denormalization: Handling scenarios where data needs restructuring for reporting or analysis purposes.

8. Can pivot tables be used for complex aggregation functions?

Answer: Yes, you can use more complex aggregate functions in pivot tables, including MAX, MIN, COUNT, AVG, SUM, etc. These functions need to be specified in the PIVOT clause.

Example using AVG:

SELECT 
    Product, 
    [Q1], [Q2], [Q3], [Q4]
FROM 
    Sales
PIVOT (
    AVG(SalesAmount)
    FOR Quarter IN ([Q1], [Q2], [Q3], [Q4])
) AS PivotTable;

9. What are the limitations of using pivoting in SQL Server?

Answer:

  • Fixed List of Columns: You need to know the column names beforehand unless dynamic SQL is used.
  • Performance: Pivoting large datasets can cause performance issues.
  • Aggregation: You must aggregate the pivot columns, which can be limiting.
  • Complexity: Writing dynamic SQL for pivoting can be complex and error-prone.

10. Are there alternatives to pivoting in SQL Server?

Answer: Yes, alternatives to pivoting include:

  • Using CROSS APPLY or OUTER APPLY with derived tables or functions.
  • Conditional Aggregation as shown in earlier examples.
  • Using EAV (Entity-Attribute-Value) Model for more flexible data modeling.
  • XML or JSON Methods for transforming and pivoting data.

You May Like This Related .NET Topic

Login to post a comment.