-1

我有这些数据显示在图像中。

在此处输入图像描述

我想像这样显示这些数据

CYNAME    04 JAN 2012   03 JAN 2012 02 JAN 2012 01 JAN-2012
CUL            12           12             12         12

我怎样才能在 oracle 10g 中实现这一点才能像那样显示。

更新

我当前的 Sql 查询是这样的

SELECT CY_NAME,
           NVL(MAX(DECODE ( CA_DATE , (SELECT MAX(CA_DATE)   FROM COTTON_ARV), CA_VALUE )),0) "04 JAN 2013",
           NVL(MAX(DECODE ( CA_DATE , (SELECT MAX(CA_DATE)-1 FROM COTTON_ARV), CA_VALUE )),0) "03 JAN 2013",
           NVL(MAX(DECODE ( CA_DATE , (SELECT MAX(CA_DATE)-2 FROM COTTON_ARV), CA_VALUE )),0) "02 JAN 2013",
           NVL(MAX(DECODE ( CA_DATE , (SELECT MAX(CA_DATE)-3 FROM COTTON_ARV), CA_VALUE )),0) "01 JAN 2013",
           NVL(MAX(DECODE ( CA_DATE , (SELECT MAX(CA_DATE)-4 FROM COTTON_ARV), CA_VALUE )),0) "31 DEC 2012",
           NVL(MAX(DECODE ( CA_DATE , (SELECT MAX(CA_DATE)-5 FROM COTTON_ARV), CA_VALUE )),0) "30 DEC 2012",
           NVL(MAX(DECODE ( CA_DATE , (SELECT MAX(CA_DATE)-6 FROM COTTON_ARV), CA_VALUE )),0) "29 DEC 2012"
    FROM      V_COTTON_ARV
    GROUP BY  CY_NAME

问题是别名是固定的,但查询中的日期是动态的。如何根据查询更改别名。或者有什么办法可以做到这一点

4

2 回答 2

2

if you wan't a dynamic number of columns you'd either have to do this approach and use a type to hold the columns (as static sql has a fixed number of columns).

SQL> create table my_table (cy_name varchar2(3), ca_date date, ca_value number);

Table created.

SQL> alter session set nls_date_format='mm/dd/yyyy';

Session altered.

SQL> insert into my_table
  2  select 'CUL' cy_name, to_date('1/4/2013') ca_date, 12 ca_value from dual
  3  union all
  4  select 'CUL' cy_name, to_date('12/31/2012') ca_date, 12 ca_value from dual
  5  union all
  6  select 'CUL' cy_name, to_date('1/3/2013') ca_date, 12 ca_value from dual
  7  union all
  8  select 'CUR' cy_name, to_date('1/6/2013') ca_date, 12 ca_value from dual
  9  union all
 10  select 'CUR' cy_name, to_date('12/6/2013') ca_date, 12 ca_value from dual;

5 rows created.

SQL>
SQL> drop type colTab;

Type dropped.

SQL> drop type colType;

Type dropped.

SQL> create type colType as object (colname varchar2(30), value number);
  2  /

Type created.

SQL> create type colTab as table of colType;
  2  /

Type created.

SQL> alter session set nls_date_format='mm/dd/yyyy';

Session altered.

SQL> col val format a80
SQL> set linesize 90
SQL> select cy_name,
  2         cast(multiset(select ca_date, ca_value
  3                         from my_table d
  4                        where d.cy_name = a.cy_name) as coltab) val
  5    from my_table a
  6  group by cy_name;

CY_ VAL(COLNAME, VALUE)
--- --------------------------------------------------------------------------------
CUR COLTAB(COLTYPE('01/06/2013', 12), COLTYPE('12/06/2013', 12))
CUL COLTAB(COLTYPE('01/04/2013', 12), COLTYPE('12/31/2012', 12), COLTYPE('01/03/2013
    ', 12))

or generate the sql first dynamically..eg:

SQL> select 'select CY_NAME, ' from dual
  2  union all
  3  select case when rownum != 1 then ',' end || str
  4    from (select distinct  'MAX(DECODE(CA_DATE, TO_DATE(''' || to_char(ca_date, 'dd-mm-yyyy') || ''', ''DD-MM-YYYY''), CA_VALUE, NULL)) as "' || to_char(ca_date, 'dd-mm-yyyy
') || '"' str
  5            from my_table a)
  6  union all
  7     select 'FROM MY_TABLE
  8  GROUP BY  CY_NAME; ' from dual
  9  ;

'SELECTCY_NAME,'
------------------------------------------------------------------------------------------
select CY_NAME,
MAX(DECODE(CA_DATE, TO_DATE('04-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "04-01-2013"
,MAX(DECODE(CA_DATE, TO_DATE('06-12-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "06-12-2013"
,MAX(DECODE(CA_DATE, TO_DATE('31-12-2012', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "31-12-2012"
,MAX(DECODE(CA_DATE, TO_DATE('03-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "03-01-2013"
,MAX(DECODE(CA_DATE, TO_DATE('06-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "06-01-2013"
FROM MY_TABLE
GROUP BY  CY_NAME;


7 rows selected.

and run it:

SQL> select CY_NAME,
  2  MAX(DECODE(CA_DATE, TO_DATE('04-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "04-01-2013"
  3  ,MAX(DECODE(CA_DATE, TO_DATE('06-12-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "06-12-2013"
  4  ,MAX(DECODE(CA_DATE, TO_DATE('31-12-2012', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "31-12-2012"
  5  ,MAX(DECODE(CA_DATE, TO_DATE('03-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "03-01-2013"
  6  ,MAX(DECODE(CA_DATE, TO_DATE('06-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "06-01-2013"
  7  FROM MY_TABLE
  8  GROUP BY  CY_NAME;

CY_ 04-01-2013 06-12-2013 31-12-2012 03-01-2013 06-01-2013
--- ---------- ---------- ---------- ---------- ----------
CUR                    12                               12
CUL         12                    12         12

UPDATE to your edit: if the number of cols in your edit is say 7:

SQL> select 'select CY_NAME, ' from dual
  2  union all
  3  select case when rownum != 1 then ',' end || str
  4    from (select 'MAX(DECODE(CA_DATE, TO_DATE('''
  5                 || to_char((d-rownum+1), 'dd-mm-yyyy')
  6                 || ''', ''DD-MM-YYYY''), CA_VALUE, NULL)) as "'
  7                 || to_char((d-rownum+1), 'dd-mm-yyyy') || '"' str
  8            from (select max(ca_date) d from cotton_arv) a
  9          connect by level <= 7 /* change to the number of cols needed */)
 10  union all
 11     select 'FROM V_COTTON_ARV
 12  GROUP BY  CY_NAME; ' from dual
 13  ;

'SELECTCY_NAME,'
------------------------------------------------------------------------------------------------
------------------------
select CY_NAME,
    MAX(DECODE(CA_DATE, TO_DATE('04-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "04-01-2013"
    ,MAX(DECODE(CA_DATE, TO_DATE('03-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "03-01-2013"
    ,MAX(DECODE(CA_DATE, TO_DATE('02-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "02-01-2013"
    ,MAX(DECODE(CA_DATE, TO_DATE('01-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "01-01-2013"
    ,MAX(DECODE(CA_DATE, TO_DATE('31-12-2012', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "31-12-2012"
    ,MAX(DECODE(CA_DATE, TO_DATE('30-12-2012', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "30-12-2012"
    ,MAX(DECODE(CA_DATE, TO_DATE('29-12-2012', 'DD-MM-YYYY'), CA_VALUE, NULL)) as "29-12-2012"
    FROM V_COTTON_ARV
    GROUP BY  CY_NAME;
于 2013-01-04T11:09:17.760 回答
0

在 Oracle 11g 之前,您不能使用简单的 SQL 语句对表进行透视。

您需要一个 PL/SQL 过程来动态构建一个像这样的透视查询:

SELECT CYNAME    
     , MAX(DECODE(CA_DATE, TO_DATE('01-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) AS "01-01-2013"
     , MAX(DECODE(CA_DATE, TO_DATE('02-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) AS "02-01-2013"
     , MAX(DECODE(CA_DATE, TO_DATE('03-01-2013', 'DD-MM-YYYY'), CA_VALUE, NULL)) AS "03-01-2013"
     , ...
FROM MY_TABLE
GROUP BY  CYNAME;

或者如果您只需要运行一次,则手动构建它。

于 2013-01-04T10:43:11.720 回答