Oracle SQL PIVOT Table

后端 未结 2 527
感动是毒
感动是毒 2020-12-21 04:05

What I have is a query, where I am selecting locations, counts, etc. Here is my query: And, I am trying to basically PIVOT the tables I believe. I have looked into PIVOT and

相关标签:
2条回答
  • 2020-12-21 04:45

    If you have access to PLSQL in your application then "user-defined aggregate functions" may be a good way to go. I have found that it provides a nice way to encapsulate transpose functionality and performs very well. I wrote one recently that took massive amounts of interval data (rows) and pivoted them into columns of interval (1-24) by day (rows). It did take a good amount of coding, but I found that the code was clear and easy to maintain.

    Here is a link to a list of string aggregation techniques available in Oracle. One of them uses a user_defined function. You essentially do the same things, but return a PLSQL collection of columns instead of an aggregated string:

    http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php#user_defined_aggregate_function

    I also liked the user-defined aggregate function due to the way Oracle handles the parallellization for performance. Here is more doc in Oracle 11g:

    http://docs.oracle.com/cd/B19306_01/appdev.102/b14289/dciaggfns.htm

    0 讨论(0)
  • 2020-12-21 04:57

    You can do something like this:

    SQL Fiddle

    Oracle 11g R2 Schema Setup:

    CREATE TABLE tbl ( "mod", "floor", "Remaining Counts", CountType ) AS
              SELECT 'dz-P-1A', 1,    37, 'CycleCount' FROM DUAL
    UNION ALL SELECT 'dz-P-1D', 1,   321, 'CycleCount' FROM DUAL
    UNION ALL SELECT 'dz-P-1T', 1,    16, 'CycleCount' FROM DUAL
    UNION ALL SELECT 'dz-P-2A', 2,    25, 'CycleCount' FROM DUAL
    UNION ALL SELECT 'dz-R-1T', 1,  3318, 'CycleCount' FROM DUAL
    UNION ALL SELECT 'dz-P-1A', 1,  6351, 'SimpleBinCount' FROM DUAL
    UNION ALL SELECT 'dz-P-1D', 1,   121, 'SimpleBinCount' FROM DUAL
    UNION ALL SELECT 'dz-P-2A', 2, 12638, 'SimpleBinCount' FROM DUAL
    UNION ALL SELECT 'dz-R-1F', 1,    68, 'SimpleBinCount' FROM DUAL
    UNION ALL SELECT 'dz-R-1O', 1,    47, 'SimpleBinCount' FROM DUAL
    UNION ALL SELECT 'dz-R-1T', 1,  2051, 'SimpleBinCount' FROM DUAL;
    

    Query 1:

    PIVOT using SUM( CASE ... ) statements:

    SELECT CountType,
           SUM( CASE "mod" WHEN 'dz-P-1A' THEN "Remaining Counts" END ) AS "P-1-A",
           SUM( CASE "mod" WHEN 'dz-P-2A' THEN "Remaining Counts" END ) AS "P-2-A",
           SUM( CASE "mod" WHEN 'dz-R-1T' THEN "Remaining Counts" END ) AS "R-1-T",
           SUM( CASE "mod" WHEN 'dz-R-1F' THEN "Remaining Counts" END ) AS "R-1-F",
           SUM( CASE "mod" WHEN 'dz-R-1O' THEN "Remaining Counts" END ) AS "R-1-O",
           SUM( CASE "mod" WHEN 'dz-P-1B' THEN "Remaining Counts" END ) AS "P-1-B",
           SUM( CASE "mod" WHEN 'dz-P-1D' THEN "Remaining Counts" END ) AS "P-1-D"
    FROM   tbl
    GROUP BY CountType
    

    Results:

    |      COUNTTYPE | P-1-A | P-2-A | R-1-T |  R-1-F |  R-1-O |  P-1-B | P-1-D |
    |----------------|-------|-------|-------|--------|--------|--------|-------|
    | SimpleBinCount |  6351 | 12638 |  2051 |     68 |     47 | (null) |   121 |
    |     CycleCount |    37 |    25 |  3318 | (null) | (null) | (null) |   321 |
    

    Query 2:

    Using PIVOT transposition:

    SELECT * FROM (
       SELECT SUBSTR( "mod", 4 ) AS "mod",
              "Remaining Counts",
              CountType
       FROM   tbl t
    )
    PIVOT
    (
       SUM("Remaining Counts")
       FOR "mod" IN ( 'P-1A', 'P-2A', 'R-1T', 'R-1F', 'R-1O', 'P-1B', 'P-1D' )
    )
    

    Results:

    |      COUNTTYPE | 'P-1A' | 'P-2A' | 'R-1T' | 'R-1F' | 'R-1O' | 'P-1B' | 'P-1D' |
    |----------------|--------|--------|--------|--------|--------|--------|--------|
    | SimpleBinCount |   6351 |  12638 |   2051 |     68 |     47 | (null) |    121 |
    |     CycleCount |     37 |     25 |   3318 | (null) | (null) | (null) |    321 |
    

    Edit - Wrapping your query:

    WITH qry AS (
      select drop_zone_id as "Mod", 
          bin_level as "Floor",
          icqa_process_properties.icqa_process_property_value as "Count Type",
          count(*) as "Remaining Counts",    
          concat(drop_zone_id, icqa_process_properties.icqa_process_property_value) as "Unique",
          to_char(sysdate,'hh:mi:ssam') as "Time Last Updated",
          to_char(sysdate, 'MM-DD-YYYY') as "Date Last Updated"
      from icqa_process_locations 
          inner join icqa_processes on icqa_processes.icqa_process_id = icqa_process_locations.icqa_process_id
          inner join icqa_process_properties on icqa_processes.icqa_process_id = icqa_process_properties.icqa_process_id
          inner join bins on bins.bin_id = icqa_process_locations.scannable_id
      where icqa_count_attempt_id is NULL and icqa_processes.process_status = ('Active')
          and drop_zone_id not like 'dz-R-1B' and drop_zone_id not like 'dz-P-1Z' and drop_zone_id not like 'dz-P-EACH_1'
          and icqa_process_properties.icqa_process_property_value in ('CycleCount', 'SimpleBinCount') 
      group by icqa_process_properties.icqa_process_property_value, bin_level, drop_zone_id
      order by icqa_process_properties.icqa_process_property_value, drop_zone_id
    )
    SELECT "Count Type",
           SUM( CASE "Mod" WHEN 'dz-P-1A' THEN "Remaining Counts" END ) AS "P-1-A",
           SUM( CASE "Mod" WHEN 'dz-P-2A' THEN "Remaining Counts" END ) AS "P-2-A",
           SUM( CASE "Mod" WHEN 'dz-R-1T' THEN "Remaining Counts" END ) AS "R-1-T",
           SUM( CASE "Mod" WHEN 'dz-R-1F' THEN "Remaining Counts" END ) AS "R-1-F",
           SUM( CASE "Mod" WHEN 'dz-R-1O' THEN "Remaining Counts" END ) AS "R-1-O",
           SUM( CASE "Mod" WHEN 'dz-P-1B' THEN "Remaining Counts" END ) AS "P-1-B",
           SUM( CASE "Mod" WHEN 'dz-P-1D' THEN "Remaining Counts" END ) AS "P-1-D"
    FROM   qry
    GROUP BY "Count Type";
    
    0 讨论(0)
提交回复
热议问题