TechWorldinfo
Technology

Step-by-Step Tutorial: Transforming Data with Oracle PIVOT and PL/SQL

Introduction

Turning rows into columns may sound like a simple rearrangement, but when dealing with large datasets and multiple grouping criteria, manual pivoting with CASE statements can be tedious and error-prone. Oracleโ€™s PIVOT clause, available since Oracle Database 11g, streamlines this transformation. Combined with PL/SQL, you can automate transformations that adapt to changing data. In this tutorial, weโ€™ll walk through each step to build, understand, and execute an Oracle PIVOT query in PL/SQL, ensuring you can apply these techniques immediately in your own projects.

Step 1: Prepare Your Sample Table

For demonstration, letโ€™s create a sample table monthly_sales:

sql

CopyEdit

CREATE TABLE monthly_sales (

  product     VARCHAR2(50),

  sales_month VARCHAR2(10),

  amount      NUMBER

);

INSERT INTO monthly_sales VALUES (‘Widget A’, ‘Jan’, 1000);

INSERT INTO monthly_sales VALUES (‘Widget A’, ‘Feb’, 1200);

INSERT INTO monthly_sales VALUES (‘Widget B’, ‘Jan’, 800);

INSERT INTO monthly_sales VALUES (‘Widget B’, ‘Mar’, 950);

— Add more rows as needed

COMMIT;

This table records monthly sales for different products.

Step 2: Write the Basic PIVOT Query

Begin by writing a PIVOT that converts months into columns:

sql

CopyEdit

SELECT *

FROM (

  SELECT product, sales_month, amount

  FROM monthly_sales

)

PIVOT (

  SUM(amount) FOR sales_month IN (‘Jan’ AS Jan, ‘Feb’ AS Feb, ‘Mar’ AS Mar)

);

What happens here?

  • Inner query selects the raw data.
  • PIVOT clause aggregates amount by sales_month.
  • The IN list defines the columns in the final output.

Step 3: Execute and Review the Result

Running the above query yields:

PRODUCTJANFEBMAR
Widget A10001200NULL
Widget B800NULL950

Observe that missing combinations appear as NULL. Replace them if necessary:

sql

CopyEdit

SELECT product,

       NVL(Jan, 0) AS Jan_Sales,

       NVL(Feb, 0) AS Feb_Sales,

       NVL(Mar, 0) AS Mar_Sales

FROM ( โ€ฆ pivot query โ€ฆ );

Step 4: Introduce PL/SQL for Parameterization

Hardcoding months isnโ€™t flexible. Use PL/SQL parameters:

plsql

CopyEdit

DECLARE

  v_year      NUMBER := 2025;

  v_sql       VARCHAR2(2000);

BEGIN

  v_sql := ‘SELECT * FROM (

              SELECT product, sales_month, amount

              FROM monthly_sales

              WHERE EXTRACT(YEAR FROM SYSDATE) = ‘ || v_year || ‘

            )

            PIVOT (

              SUM(amount) FOR sales_month IN (”Jan” AS Jan, ”Feb” AS Feb, ”Mar” AS Mar)

            )’;

  EXECUTE IMMEDIATE v_sql;

END;

Replace the static year with a bind variable or procedure parameter for more flexibility.

Step 5: Build a Stored Procedure

Encapsulate pivot logic in a stored procedure that accepts month list dynamically:

plsql

CopyEdit

CREATE OR REPLACE PROCEDURE pivot_sales(p_months IN VARCHAR2) AS

  v_sql VARCHAR2(4000);

BEGIN

  v_sql := ‘SELECT * FROM (

              SELECT product, sales_month, amount

              FROM monthly_sales

            )

            PIVOT (

              SUM(amount) FOR sales_month IN (‘ || p_months || ‘)

            )’;

  OPEN :result_cursor FOR v_sql;

END;

Call it with:

plsql

CopyEdit

VARIABLE rc REFCURSOR;

EXEC pivot_sales(”’Jan” AS Jan, ”Feb” AS Feb, ”Mar” AS Mar’);

PRINT rc;

Step 6: Automate Dynamic Month List Generation

Generate the month list automatically using LISTAGG:

plsql

CopyEdit

DECLARE

  v_month_list VARCHAR2(1000);

BEGIN

  SELECT LISTAGG(””||sales_month||”’ AS ‘||sales_month, ‘, ‘)

    INTO v_month_list

    FROM (SELECT DISTINCT sales_month FROM monthly_sales);

  DBMS_OUTPUT.PUT_LINE(‘Generated IN list: ‘ || v_month_list);

END;

Plug v_month_list into your procedure call to handle new months without code changes.

Step 7: Schedule the Report

Use DBMS_SCHEDULER to run your pivot procedure nightly:

plsql

CopyEdit

BEGIN

  DBMS_SCHEDULER.CREATE_JOB (

    job_name        => ‘sales_pivot_job’,

    job_type        => ‘STORED_PROCEDURE’,

    job_action      => ‘pivot_sales’,

    start_date      => SYSTIMESTAMP,

    repeat_interval => ‘FREQ=DAILY; BYHOUR=2; BYMINUTE=0’,

    enabled         => TRUE

  );

END;

This job executes at 2:00 AM each day, refreshing your pivoted results.

Conclusion

Converting vertical data into horizontal, easily comparable formats no longer requires complex CASE expressions or front-end workarounds. With Oracle PIVOT and PL/SQL, you have a robust, performance-optimized means to build dynamic reports that adapt to changing data scenarios. By following this step-by-step tutorial, from table preparation to job scheduling, youโ€™ll be able to transform raw datasets into clear, actionable insights with minimal manual intervention. Embrace Oracle PIVOT to streamline your reporting workflows and empower stakeholders with timely, accurate cross-tabular data.

Related posts

Why the Free Picker Wheel Is a Must-Have Tool for Teachers and Event Planners

admin

Discover the Versatility and Efficiency of Combi Ovens for Your Commercial Kitchen

admin

Precision Agriculture 101: Getting Started with John Deere Technology

admin

Leave a Comment