重新排列将值转换为列名称的表

时间:2015-05-04 06:23:56

标签: sql oracle oracle-sqldeveloper

由于实现动态数据输入工具的XML实现,我留下了下表

TRGID   C_NAME     I_ID COLUMNID    TARGET_DESC     DEPT_NAME   VALUE

20158   Outlook     2   1000        Production      Operations  2.501
20158   Outlook     4   1000        Production      Operations  1.5
20158   Outlook     3   1000        Production      Operations  0.2
20158   Outlook     1   1000        Production      Operations  1.9
20158   Target      1   2111        Production      Operations  2.1
20158   Target      4   2111        Production      Operations  1.2
20158   Target      2   2111        Production      Operations  11.2
20158   Target      3   2111        Production      Operations  1.58
20158   Month       4   3222        Production      Operations  1-May-2010
20158   Month       3   3222        Production      Operations  1-Apr-2010
20158   Month       2   3222        Production      Operations  1-Jan-2015
20158   Month       1   3222        Production      Operations  1-Mar-2015
20158   Actual      4   4333        Production      Operations  2.5
20158   Actual      3   4333        Production      Operations  3.5
20158   Actual      2   4333        Production      Operations  10.8
20158   Actual      1   4333        Production      Operations  2
20163   Month       2   1000        Maintenance     Operations  1-Feb-2015
20163   Month       1   1000        Maintenance     Operations  1-Jan-2010
20163   Outlook     2   2111        Maintenance     Operations  18.56
20163   Outlook     1   2111        Maintenance     Operations  2.3
20163   Actual      2   3222        Maintenance     Operations  28.2
20163   Actual      1   3222        Maintenance     Operations  1.4
20163   Goal        2   4333        Maintenance     Operations  3.98
20163   Goal        1   4333        Maintenance     Operations  3.6

我希望结果如下

TRGID   I_ID      Month      Actual  Outlook    Target      Goal
20158    1      1-Mar-2015     2       1.9        2.1   
20158    2      1-Jan-2015     10.8    2.501      11.2  
20158    3      1-Apr-2010     3.5     0.2        1.58  
20158    4      1-May-2010     2.5     1.5        1.2   
20163    1      1-Jan-2010     1.4     2.3                  3.6
20163    2      1-Feb-2015     28.2    18.56                3.98

我想要一个能够适应数据变化而不仅仅是当前数据的解决方案。

我正在使用Oracle 10g

1 个答案:

答案 0 :(得分:2)

如果您有Oracle 11g

,请使用Pivot
WITH table_(TRGID, C_NAME, I_ID, COLUMNID, TARGET_DESC, DEPT_NAME, VALUE) AS 
(
    select 20158, 'Outlook', 2, 1000, 'Production', 'Operations', '2.501' from dual union all
    select 20158, 'Outlook', 4, 1000, 'Production', 'Operations', '1.5' from dual union all
    select 20158, 'Outlook', 3, 1000, 'Production', 'Operations', '0.2' from dual union all
    select 20158, 'Outlook', 1, 1000, 'Production', 'Operations', '1.9' from dual union all
    select 20158, 'Target', 1, 2111, 'Production', 'Operations', '2.1' from dual union all
    select 20158, 'Target', 4, 2111, 'Production', 'Operations', '1.2' from dual union all
    select 20158, 'Target', 2, 2111, 'Production', 'Operations', '11.2' from dual union all
    select 20158, 'Target', 3, 2111, 'Production', 'Operations', '1.58' from dual union all
    select 20158, 'Month', 4, 3222, 'Production', 'Operations', '1-May-2010' from dual union all
    select 20158, 'Month', 3, 3222, 'Production', 'Operations', '1-Apr-2010' from dual union all
    select 20158, 'Month', 2, 3222, 'Production', 'Operations', '1-Jan-2015' from dual union all
    select 20158, 'Month', 1, 3222, 'Production', 'Operations', '1-Mar-2015' from dual union all
    select 20158, 'Actual', 4, 4333, 'Production', 'Operations', '2.5' from dual union all
    select 20158, 'Actual', 3, 4333, 'Production', 'Operations', '3.5' from dual union all
    select 20158, 'Actual', 2, 4333, 'Production', 'Operations', '10.8' from dual union all
    select 20158, 'Actual', 1, 4333, 'Production', 'Operations', '2' from dual union all
    select 20163, 'Month', 2, 1000, 'Maintenance', 'Operations', '1-Feb-2015' from dual union all
    select 20163, 'Month', 1, 1000, 'Maintenance', 'Operations', '1-Jan-2010' from dual union all
    select 20163, 'Outlook', 2, 2111, 'Maintenance', 'Operations', '18.56' from dual union all
    select 20163, 'Outlook', 1, 2111, 'Maintenance', 'Operations', '2.3' from dual union all
    select 20163, 'Actual', 2, 3222, 'Maintenance', 'Operations', '28.2' from dual union all
    select 20163, 'Actual', 1, 3222, 'Maintenance', 'Operations', '1.4' from dual union all
    select 20163, 'Goal', 2, 4333, 'Maintenance', 'Operations', '3.98' from dual union all
    select 20163, 'Goal', 1, 4333, 'Maintenance', 'Operations', '3.6' from dual)
-- End if data Preparation
    SELECT *
      FROM (SELECT trgid,
                   c_name,
                   i_id,
                   VALUE
              FROM table_) pivot(MIN(VALUE) FOR c_name IN('Month' AS MONTH,
                                                          'Actual' AS actual,
                                                          'Outlook' as outlook,
                                                          'Target' AS target,
                                                          'Goal' AS goal))

输出

| TRGID | I_ID |      MONTH | ACTUAL | OUTLOOK | TARGET |   GOAL |
|-------|------|------------|--------|---------|--------|--------|
| 20158 |    2 | 1-Jan-2015 |   10.8 |   2.501 |   11.2 | (null) |
| 20163 |    1 | 1-Jan-2010 |    1.4 |     2.3 | (null) |    3.6 |
| 20163 |    2 | 1-Feb-2015 |   28.2 |   18.56 | (null) |   3.98 |
| 20158 |    1 | 1-Mar-2015 |      2 |     1.9 |    2.1 | (null) |
| 20158 |    4 | 1-May-2010 |    2.5 |     1.5 |    1.2 | (null) |
| 20158 |    3 | 1-Apr-2010 |    3.5 |     0.2 |   1.58 | (null) |

对于版本< 11 g,使用以下查询,

SELECT trgid,
       i_id,
       MIN(CASE c_name WHEN 'Month' THEN VALUE ELSE NULL END) AS MONTH,
       MIN(CASE c_name WHEN 'Actual' THEN VALUE ELSE NULL END) AS actual,
       MIN(CASE c_name WHEN 'Outlook' THEN VALUE ELSE NULL END) AS outlook,
       MIN(CASE c_name WHEN 'Target' THEN VALUE ELSE NULL END) AS target,
       MIN(CASE c_name WHEN 'Goal' THEN VALUE ELSE NULL END) AS goal
  FROM table_
 GROUP BY trgid, i_id;