Oracle SQL Pivot query not grouping correctly












1















For each employee in a database, I'm trying to produce a list of the total number of items they have sold which have generated a set amount of profit (if they have sold any), i.e.



+--------------+----------+----------+----------+
| EmployeeName | Product1 | Product2 | Product3 |
+--------------+----------+----------+----------+
| John Smith | 4 | 7 | 1 |
+--------------+----------+----------+----------+


where Product1, Product2 and Product3 represent products with IDs 1, 2 and 3, which happen to have made >x profit.



The solution I have so far is a dynamic pivot where I find the product IDs that have made >x profit, and construct the SELECT and PIVOT clauses using LISTAGG. However, when I run the query on a test dataset, the vast majority of the output consists of empty fields under the Productn columns, and each employee has many entries that aren't grouped together.



I think this is because the input to the pivot is not being filtered to remove products which haven't made >x, but I don't know how I can filter it whilst still using the pivot, since I can't use GROUP BY/HAVING or WHERE.



The query I have so far is:



SELECT FName || '' '' || LName AS EmployeeName, ' || selectClause || ' FROM STAFF_ORDERS
INNER JOIN STAFF ON STAFF_ORDERS.StaffID = STAFF.StaffID
INNER JOIN STAFF_EXP_TOTALS ON STAFF_EXP_TOTALS.StaffID = STAFF_ORDERS.StaffID
INNER JOIN ORDER_PRODUCTS ON STAFF_ORDERS.OrderID = ORDER_PRODUCTS.OrderID
PIVOT (SUM(ProductQuantity) FOR ProductID IN ('|| pivotClause || ')) ORDER BY TotalValueSold DESC


A section of the current output looks like this:current output



If anyone knows how I can fix the query, or a better way to approach this, that would be a great help. If you need more information, let me know and I'll provide it.



Thanks,



James










share|improve this question



























    1















    For each employee in a database, I'm trying to produce a list of the total number of items they have sold which have generated a set amount of profit (if they have sold any), i.e.



    +--------------+----------+----------+----------+
    | EmployeeName | Product1 | Product2 | Product3 |
    +--------------+----------+----------+----------+
    | John Smith | 4 | 7 | 1 |
    +--------------+----------+----------+----------+


    where Product1, Product2 and Product3 represent products with IDs 1, 2 and 3, which happen to have made >x profit.



    The solution I have so far is a dynamic pivot where I find the product IDs that have made >x profit, and construct the SELECT and PIVOT clauses using LISTAGG. However, when I run the query on a test dataset, the vast majority of the output consists of empty fields under the Productn columns, and each employee has many entries that aren't grouped together.



    I think this is because the input to the pivot is not being filtered to remove products which haven't made >x, but I don't know how I can filter it whilst still using the pivot, since I can't use GROUP BY/HAVING or WHERE.



    The query I have so far is:



    SELECT FName || '' '' || LName AS EmployeeName, ' || selectClause || ' FROM STAFF_ORDERS
    INNER JOIN STAFF ON STAFF_ORDERS.StaffID = STAFF.StaffID
    INNER JOIN STAFF_EXP_TOTALS ON STAFF_EXP_TOTALS.StaffID = STAFF_ORDERS.StaffID
    INNER JOIN ORDER_PRODUCTS ON STAFF_ORDERS.OrderID = ORDER_PRODUCTS.OrderID
    PIVOT (SUM(ProductQuantity) FOR ProductID IN ('|| pivotClause || ')) ORDER BY TotalValueSold DESC


    A section of the current output looks like this:current output



    If anyone knows how I can fix the query, or a better way to approach this, that would be a great help. If you need more information, let me know and I'll provide it.



    Thanks,



    James










    share|improve this question

























      1












      1








      1








      For each employee in a database, I'm trying to produce a list of the total number of items they have sold which have generated a set amount of profit (if they have sold any), i.e.



      +--------------+----------+----------+----------+
      | EmployeeName | Product1 | Product2 | Product3 |
      +--------------+----------+----------+----------+
      | John Smith | 4 | 7 | 1 |
      +--------------+----------+----------+----------+


      where Product1, Product2 and Product3 represent products with IDs 1, 2 and 3, which happen to have made >x profit.



      The solution I have so far is a dynamic pivot where I find the product IDs that have made >x profit, and construct the SELECT and PIVOT clauses using LISTAGG. However, when I run the query on a test dataset, the vast majority of the output consists of empty fields under the Productn columns, and each employee has many entries that aren't grouped together.



      I think this is because the input to the pivot is not being filtered to remove products which haven't made >x, but I don't know how I can filter it whilst still using the pivot, since I can't use GROUP BY/HAVING or WHERE.



      The query I have so far is:



      SELECT FName || '' '' || LName AS EmployeeName, ' || selectClause || ' FROM STAFF_ORDERS
      INNER JOIN STAFF ON STAFF_ORDERS.StaffID = STAFF.StaffID
      INNER JOIN STAFF_EXP_TOTALS ON STAFF_EXP_TOTALS.StaffID = STAFF_ORDERS.StaffID
      INNER JOIN ORDER_PRODUCTS ON STAFF_ORDERS.OrderID = ORDER_PRODUCTS.OrderID
      PIVOT (SUM(ProductQuantity) FOR ProductID IN ('|| pivotClause || ')) ORDER BY TotalValueSold DESC


      A section of the current output looks like this:current output



      If anyone knows how I can fix the query, or a better way to approach this, that would be a great help. If you need more information, let me know and I'll provide it.



      Thanks,



      James










      share|improve this question














      For each employee in a database, I'm trying to produce a list of the total number of items they have sold which have generated a set amount of profit (if they have sold any), i.e.



      +--------------+----------+----------+----------+
      | EmployeeName | Product1 | Product2 | Product3 |
      +--------------+----------+----------+----------+
      | John Smith | 4 | 7 | 1 |
      +--------------+----------+----------+----------+


      where Product1, Product2 and Product3 represent products with IDs 1, 2 and 3, which happen to have made >x profit.



      The solution I have so far is a dynamic pivot where I find the product IDs that have made >x profit, and construct the SELECT and PIVOT clauses using LISTAGG. However, when I run the query on a test dataset, the vast majority of the output consists of empty fields under the Productn columns, and each employee has many entries that aren't grouped together.



      I think this is because the input to the pivot is not being filtered to remove products which haven't made >x, but I don't know how I can filter it whilst still using the pivot, since I can't use GROUP BY/HAVING or WHERE.



      The query I have so far is:



      SELECT FName || '' '' || LName AS EmployeeName, ' || selectClause || ' FROM STAFF_ORDERS
      INNER JOIN STAFF ON STAFF_ORDERS.StaffID = STAFF.StaffID
      INNER JOIN STAFF_EXP_TOTALS ON STAFF_EXP_TOTALS.StaffID = STAFF_ORDERS.StaffID
      INNER JOIN ORDER_PRODUCTS ON STAFF_ORDERS.OrderID = ORDER_PRODUCTS.OrderID
      PIVOT (SUM(ProductQuantity) FOR ProductID IN ('|| pivotClause || ')) ORDER BY TotalValueSold DESC


      A section of the current output looks like this:current output



      If anyone knows how I can fix the query, or a better way to approach this, that would be a great help. If you need more information, let me know and I'll provide it.



      Thanks,



      James







      sql oracle pivot oracle12c






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 21:14









      jamerstjamerst

      182




      182
























          1 Answer
          1






          active

          oldest

          votes


















          1














          For the following queries, a simplified STAFF_ORDERS table and the (sample) HR.EMPLOYEES table have been used (Oracle 12c). Principle: join all required tables, pivot, and filter. Maybe this example will help you -



          Test tables and data



          create table staff_orders (
          id number primary key
          , employee_id number
          , product_code varchar2( 5 )
          , quantity number
          );

          insert into staff_orders values ( 1, 101, 'A', 10);
          insert into staff_orders values ( 2, 101, 'B', 20);
          insert into staff_orders values ( 3, 101, 'C', 30);
          insert into staff_orders values ( 4, 102, 'A', 40);
          insert into staff_orders values ( 5, 102, 'C', 50);
          insert into staff_orders values ( 6, 103, 'A', 60);
          insert into staff_orders values ( 7, 103, 'B', 70);
          insert into staff_orders values ( 8, 103, 'C', 80);
          insert into staff_orders values ( 9, 103, 'D', 90);
          insert into staff_orders values (10, 104, 'A', 100);
          insert into staff_orders values (11, 101, 'A', 10);
          insert into staff_orders values (12, 101, 'B', 20);
          insert into staff_orders values (13, 101, 'C', 30);
          insert into staff_orders values (14, 102, 'A', 40);
          insert into staff_orders values (15, 102, 'C', 50);
          insert into staff_orders values (16, 103, 'A', 60);
          insert into staff_orders values (17, 103, 'B', 70);
          insert into staff_orders values (18, 103, 'C', 80);
          insert into staff_orders values (19, 103, 'D', 90);
          insert into staff_orders values (20, 104, 'A', 100);
          commit;


          Table STAFF_ORDERS



          select * from staff_orders;

          ID EMPLOYEE_ID PRODU QUANTITY
          ---------- ----------- ----- ----------
          1 101 A 10
          2 101 B 20
          3 101 C 30
          4 102 A 40
          5 102 C 50
          6 103 A 60
          7 103 B 70
          8 103 C 80
          9 103 D 90
          10 104 A 100
          -- etc...


          Table HR.EMPLOYEES



          select employee_id, first_name, last_name
          from hr.employees
          where employee_id in ( 101, 102, 103, 104 ) ;

          EMPLOYEE_ID FIRST_NAME LAST_NAME
          102 Lex De Haan
          104 Bruce Ernst
          103 Alexander Hunold
          101 Neena Kochhar


          Join the tables and adjust the column(s) as required.



          select 
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_CODE QUANTITY
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          102 Lex De Haan C 50
          -- ...
          103 Alexander Hunold C 80
          103 Alexander Hunold B 70
          103 Alexander Hunold A 60
          104 Bruce Ernst A 100
          104 Bruce Ernst A 100


          Pivot -> sum of quantities.



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          102 Lex De Haan 80 NULL 100
          103 Alexander Hunold 120 140 160
          101 Neena Kochhar 20 40 60


          Filter: product total > 100 (add a WHERE clause to the previous query).



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          where product_a_total > 100
          or product_b_total > 100 -- use AND here if need be
          or product_c_total > 100 -- use AND here if need be
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          103 Alexander Hunold 120 140 160





          share|improve this answer


























          • Thanks for the reply, but I already managed to fix it by filtering out the unnecessary columns, and it's now grouping correctly.

            – jamerst
            Nov 24 '18 at 15:18











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453009%2foracle-sql-pivot-query-not-grouping-correctly%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          For the following queries, a simplified STAFF_ORDERS table and the (sample) HR.EMPLOYEES table have been used (Oracle 12c). Principle: join all required tables, pivot, and filter. Maybe this example will help you -



          Test tables and data



          create table staff_orders (
          id number primary key
          , employee_id number
          , product_code varchar2( 5 )
          , quantity number
          );

          insert into staff_orders values ( 1, 101, 'A', 10);
          insert into staff_orders values ( 2, 101, 'B', 20);
          insert into staff_orders values ( 3, 101, 'C', 30);
          insert into staff_orders values ( 4, 102, 'A', 40);
          insert into staff_orders values ( 5, 102, 'C', 50);
          insert into staff_orders values ( 6, 103, 'A', 60);
          insert into staff_orders values ( 7, 103, 'B', 70);
          insert into staff_orders values ( 8, 103, 'C', 80);
          insert into staff_orders values ( 9, 103, 'D', 90);
          insert into staff_orders values (10, 104, 'A', 100);
          insert into staff_orders values (11, 101, 'A', 10);
          insert into staff_orders values (12, 101, 'B', 20);
          insert into staff_orders values (13, 101, 'C', 30);
          insert into staff_orders values (14, 102, 'A', 40);
          insert into staff_orders values (15, 102, 'C', 50);
          insert into staff_orders values (16, 103, 'A', 60);
          insert into staff_orders values (17, 103, 'B', 70);
          insert into staff_orders values (18, 103, 'C', 80);
          insert into staff_orders values (19, 103, 'D', 90);
          insert into staff_orders values (20, 104, 'A', 100);
          commit;


          Table STAFF_ORDERS



          select * from staff_orders;

          ID EMPLOYEE_ID PRODU QUANTITY
          ---------- ----------- ----- ----------
          1 101 A 10
          2 101 B 20
          3 101 C 30
          4 102 A 40
          5 102 C 50
          6 103 A 60
          7 103 B 70
          8 103 C 80
          9 103 D 90
          10 104 A 100
          -- etc...


          Table HR.EMPLOYEES



          select employee_id, first_name, last_name
          from hr.employees
          where employee_id in ( 101, 102, 103, 104 ) ;

          EMPLOYEE_ID FIRST_NAME LAST_NAME
          102 Lex De Haan
          104 Bruce Ernst
          103 Alexander Hunold
          101 Neena Kochhar


          Join the tables and adjust the column(s) as required.



          select 
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_CODE QUANTITY
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          102 Lex De Haan C 50
          -- ...
          103 Alexander Hunold C 80
          103 Alexander Hunold B 70
          103 Alexander Hunold A 60
          104 Bruce Ernst A 100
          104 Bruce Ernst A 100


          Pivot -> sum of quantities.



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          102 Lex De Haan 80 NULL 100
          103 Alexander Hunold 120 140 160
          101 Neena Kochhar 20 40 60


          Filter: product total > 100 (add a WHERE clause to the previous query).



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          where product_a_total > 100
          or product_b_total > 100 -- use AND here if need be
          or product_c_total > 100 -- use AND here if need be
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          103 Alexander Hunold 120 140 160





          share|improve this answer


























          • Thanks for the reply, but I already managed to fix it by filtering out the unnecessary columns, and it's now grouping correctly.

            – jamerst
            Nov 24 '18 at 15:18
















          1














          For the following queries, a simplified STAFF_ORDERS table and the (sample) HR.EMPLOYEES table have been used (Oracle 12c). Principle: join all required tables, pivot, and filter. Maybe this example will help you -



          Test tables and data



          create table staff_orders (
          id number primary key
          , employee_id number
          , product_code varchar2( 5 )
          , quantity number
          );

          insert into staff_orders values ( 1, 101, 'A', 10);
          insert into staff_orders values ( 2, 101, 'B', 20);
          insert into staff_orders values ( 3, 101, 'C', 30);
          insert into staff_orders values ( 4, 102, 'A', 40);
          insert into staff_orders values ( 5, 102, 'C', 50);
          insert into staff_orders values ( 6, 103, 'A', 60);
          insert into staff_orders values ( 7, 103, 'B', 70);
          insert into staff_orders values ( 8, 103, 'C', 80);
          insert into staff_orders values ( 9, 103, 'D', 90);
          insert into staff_orders values (10, 104, 'A', 100);
          insert into staff_orders values (11, 101, 'A', 10);
          insert into staff_orders values (12, 101, 'B', 20);
          insert into staff_orders values (13, 101, 'C', 30);
          insert into staff_orders values (14, 102, 'A', 40);
          insert into staff_orders values (15, 102, 'C', 50);
          insert into staff_orders values (16, 103, 'A', 60);
          insert into staff_orders values (17, 103, 'B', 70);
          insert into staff_orders values (18, 103, 'C', 80);
          insert into staff_orders values (19, 103, 'D', 90);
          insert into staff_orders values (20, 104, 'A', 100);
          commit;


          Table STAFF_ORDERS



          select * from staff_orders;

          ID EMPLOYEE_ID PRODU QUANTITY
          ---------- ----------- ----- ----------
          1 101 A 10
          2 101 B 20
          3 101 C 30
          4 102 A 40
          5 102 C 50
          6 103 A 60
          7 103 B 70
          8 103 C 80
          9 103 D 90
          10 104 A 100
          -- etc...


          Table HR.EMPLOYEES



          select employee_id, first_name, last_name
          from hr.employees
          where employee_id in ( 101, 102, 103, 104 ) ;

          EMPLOYEE_ID FIRST_NAME LAST_NAME
          102 Lex De Haan
          104 Bruce Ernst
          103 Alexander Hunold
          101 Neena Kochhar


          Join the tables and adjust the column(s) as required.



          select 
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_CODE QUANTITY
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          102 Lex De Haan C 50
          -- ...
          103 Alexander Hunold C 80
          103 Alexander Hunold B 70
          103 Alexander Hunold A 60
          104 Bruce Ernst A 100
          104 Bruce Ernst A 100


          Pivot -> sum of quantities.



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          102 Lex De Haan 80 NULL 100
          103 Alexander Hunold 120 140 160
          101 Neena Kochhar 20 40 60


          Filter: product total > 100 (add a WHERE clause to the previous query).



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          where product_a_total > 100
          or product_b_total > 100 -- use AND here if need be
          or product_c_total > 100 -- use AND here if need be
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          103 Alexander Hunold 120 140 160





          share|improve this answer


























          • Thanks for the reply, but I already managed to fix it by filtering out the unnecessary columns, and it's now grouping correctly.

            – jamerst
            Nov 24 '18 at 15:18














          1












          1








          1







          For the following queries, a simplified STAFF_ORDERS table and the (sample) HR.EMPLOYEES table have been used (Oracle 12c). Principle: join all required tables, pivot, and filter. Maybe this example will help you -



          Test tables and data



          create table staff_orders (
          id number primary key
          , employee_id number
          , product_code varchar2( 5 )
          , quantity number
          );

          insert into staff_orders values ( 1, 101, 'A', 10);
          insert into staff_orders values ( 2, 101, 'B', 20);
          insert into staff_orders values ( 3, 101, 'C', 30);
          insert into staff_orders values ( 4, 102, 'A', 40);
          insert into staff_orders values ( 5, 102, 'C', 50);
          insert into staff_orders values ( 6, 103, 'A', 60);
          insert into staff_orders values ( 7, 103, 'B', 70);
          insert into staff_orders values ( 8, 103, 'C', 80);
          insert into staff_orders values ( 9, 103, 'D', 90);
          insert into staff_orders values (10, 104, 'A', 100);
          insert into staff_orders values (11, 101, 'A', 10);
          insert into staff_orders values (12, 101, 'B', 20);
          insert into staff_orders values (13, 101, 'C', 30);
          insert into staff_orders values (14, 102, 'A', 40);
          insert into staff_orders values (15, 102, 'C', 50);
          insert into staff_orders values (16, 103, 'A', 60);
          insert into staff_orders values (17, 103, 'B', 70);
          insert into staff_orders values (18, 103, 'C', 80);
          insert into staff_orders values (19, 103, 'D', 90);
          insert into staff_orders values (20, 104, 'A', 100);
          commit;


          Table STAFF_ORDERS



          select * from staff_orders;

          ID EMPLOYEE_ID PRODU QUANTITY
          ---------- ----------- ----- ----------
          1 101 A 10
          2 101 B 20
          3 101 C 30
          4 102 A 40
          5 102 C 50
          6 103 A 60
          7 103 B 70
          8 103 C 80
          9 103 D 90
          10 104 A 100
          -- etc...


          Table HR.EMPLOYEES



          select employee_id, first_name, last_name
          from hr.employees
          where employee_id in ( 101, 102, 103, 104 ) ;

          EMPLOYEE_ID FIRST_NAME LAST_NAME
          102 Lex De Haan
          104 Bruce Ernst
          103 Alexander Hunold
          101 Neena Kochhar


          Join the tables and adjust the column(s) as required.



          select 
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_CODE QUANTITY
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          102 Lex De Haan C 50
          -- ...
          103 Alexander Hunold C 80
          103 Alexander Hunold B 70
          103 Alexander Hunold A 60
          104 Bruce Ernst A 100
          104 Bruce Ernst A 100


          Pivot -> sum of quantities.



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          102 Lex De Haan 80 NULL 100
          103 Alexander Hunold 120 140 160
          101 Neena Kochhar 20 40 60


          Filter: product total > 100 (add a WHERE clause to the previous query).



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          where product_a_total > 100
          or product_b_total > 100 -- use AND here if need be
          or product_c_total > 100 -- use AND here if need be
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          103 Alexander Hunold 120 140 160





          share|improve this answer















          For the following queries, a simplified STAFF_ORDERS table and the (sample) HR.EMPLOYEES table have been used (Oracle 12c). Principle: join all required tables, pivot, and filter. Maybe this example will help you -



          Test tables and data



          create table staff_orders (
          id number primary key
          , employee_id number
          , product_code varchar2( 5 )
          , quantity number
          );

          insert into staff_orders values ( 1, 101, 'A', 10);
          insert into staff_orders values ( 2, 101, 'B', 20);
          insert into staff_orders values ( 3, 101, 'C', 30);
          insert into staff_orders values ( 4, 102, 'A', 40);
          insert into staff_orders values ( 5, 102, 'C', 50);
          insert into staff_orders values ( 6, 103, 'A', 60);
          insert into staff_orders values ( 7, 103, 'B', 70);
          insert into staff_orders values ( 8, 103, 'C', 80);
          insert into staff_orders values ( 9, 103, 'D', 90);
          insert into staff_orders values (10, 104, 'A', 100);
          insert into staff_orders values (11, 101, 'A', 10);
          insert into staff_orders values (12, 101, 'B', 20);
          insert into staff_orders values (13, 101, 'C', 30);
          insert into staff_orders values (14, 102, 'A', 40);
          insert into staff_orders values (15, 102, 'C', 50);
          insert into staff_orders values (16, 103, 'A', 60);
          insert into staff_orders values (17, 103, 'B', 70);
          insert into staff_orders values (18, 103, 'C', 80);
          insert into staff_orders values (19, 103, 'D', 90);
          insert into staff_orders values (20, 104, 'A', 100);
          commit;


          Table STAFF_ORDERS



          select * from staff_orders;

          ID EMPLOYEE_ID PRODU QUANTITY
          ---------- ----------- ----- ----------
          1 101 A 10
          2 101 B 20
          3 101 C 30
          4 102 A 40
          5 102 C 50
          6 103 A 60
          7 103 B 70
          8 103 C 80
          9 103 D 90
          10 104 A 100
          -- etc...


          Table HR.EMPLOYEES



          select employee_id, first_name, last_name
          from hr.employees
          where employee_id in ( 101, 102, 103, 104 ) ;

          EMPLOYEE_ID FIRST_NAME LAST_NAME
          102 Lex De Haan
          104 Bruce Ernst
          103 Alexander Hunold
          101 Neena Kochhar


          Join the tables and adjust the column(s) as required.



          select 
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_CODE QUANTITY
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          101 Neena Kochhar C 30
          101 Neena Kochhar B 20
          101 Neena Kochhar A 10
          102 Lex De Haan C 50
          -- ...
          103 Alexander Hunold C 80
          103 Alexander Hunold B 70
          103 Alexander Hunold A 60
          104 Bruce Ernst A 100
          104 Bruce Ernst A 100


          Pivot -> sum of quantities.



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          102 Lex De Haan 80 NULL 100
          103 Alexander Hunold 120 140 160
          101 Neena Kochhar 20 40 60


          Filter: product total > 100 (add a WHERE clause to the previous query).



          select *
          from (
          select
          E.employee_id
          , E.first_name || ' ' || E.last_name as employee_name
          , O.product_code
          , O.quantity
          from hr.employees E
          join staff_orders O on E.employee_id = O.employee_id
          )
          pivot (
          sum( quantity ) as total for ( product_code ) in (
          'A' AS product_a
          , 'B' AS product_b
          , 'C' AS product_c
          )
          )
          where product_a_total > 100
          or product_b_total > 100 -- use AND here if need be
          or product_c_total > 100 -- use AND here if need be
          ;

          EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
          104 Bruce Ernst 200 NULL NULL
          103 Alexander Hunold 120 140 160






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 24 '18 at 12:26

























          answered Nov 24 '18 at 11:00









          stefanstefan

          886146




          886146













          • Thanks for the reply, but I already managed to fix it by filtering out the unnecessary columns, and it's now grouping correctly.

            – jamerst
            Nov 24 '18 at 15:18



















          • Thanks for the reply, but I already managed to fix it by filtering out the unnecessary columns, and it's now grouping correctly.

            – jamerst
            Nov 24 '18 at 15:18

















          Thanks for the reply, but I already managed to fix it by filtering out the unnecessary columns, and it's now grouping correctly.

          – jamerst
          Nov 24 '18 at 15:18





          Thanks for the reply, but I already managed to fix it by filtering out the unnecessary columns, and it's now grouping correctly.

          – jamerst
          Nov 24 '18 at 15:18




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453009%2foracle-sql-pivot-query-not-grouping-correctly%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Costa Masnaga

          Fotorealismo

          Sidney Franklin