转动每n个记录

时间:2014-08-06 09:38:17

标签: sql oracle plsql pivot-table

我有一张这样的表:

+----------------------------------------------------+
| PI  | VS  | S | HID | DESC          | MS   | QT    |
+----------------------------------------------------+
| 195 | 152 | 0 | 554 | Description 1 | 2013 |       |
| 195 | 152 | 0 | 554 | Description 1 | JAN  | 3677  |
| 195 | 152 | 0 | 554 | Description 1 | FEB  | 4187  |
| 195 | 152 | 0 | 554 | Description 1 | MAR  | 3344  |
| 195 | 152 | 0 | 554 | Description 1 | APR  | 4001  |
| 195 | 152 | 0 | 554 | Description 1 | MAY  | 4966  |
| 195 | 152 | 0 | 554 | Description 1 | JUN  | 1079  |
| 195 | 152 | 0 | 554 | Description 1 | JUL  | 452   |
| 195 | 152 | 0 | 554 | Description 1 | AUG  | 2224  |
| 195 | 152 | 0 | 554 | Description 1 | SEP  | 45478 |
| 195 | 152 | 0 | 554 | Description 1 | OCT  | 2104  |
| 195 | 152 | 0 | 554 | Description 1 | NOV  | 122   |
| 195 | 152 | 0 | 554 | Description 1 | DEC  | 110   |
+----------------------------------------------------+
| 195 | 152 | 0 | 554 | Description 1 | 2013 |       |
| 195 | 152 | 0 | 554 | Description 1 | JAN  | 3377  |
| 195 | 152 | 0 | 554 | Description 1 | FEB  | 4187  |
| 195 | 152 | 0 | 554 | Description 1 | MAR  | 3344  |
| 195 | 152 | 0 | 554 | Description 1 | APR  | 4001  |
| 195 | 152 | 0 | 554 | Description 1 | MAY  | 4966  |
| 195 | 152 | 0 | 554 | Description 1 | JUN  | 1076  |
| 195 | 152 | 0 | 554 | Description 1 | JUL  | 452   |
| 195 | 152 | 0 | 554 | Description 1 | AUG  | 2224  |
| 195 | 152 | 0 | 554 | Description 1 | SEP  | 45478 |
| 195 | 152 | 0 | 554 | Description 1 | OCT  | 21554 |
| 195 | 152 | 0 | 554 | Description 1 | NOV  | 122   |
| 195 | 152 | 0 | 554 | Description 1 | DEC  | 110   |
+----------------------------------------------------+

我想提取第一行,然后将下一个12作为字段连接起来,使用它们的内容作为列名。

类似的东西:

+--------------------------------------------------------------------------------------------------------------------------------+
| PI  | VS  | S | HID | DESC           | YEAR | JAN  | FEB  | MAR  | APR  | MAY  | JUN  | JUL | AUG  |  SEP  | OCT   | NOV | DEC |
+--------------------------------------------------------------------------------------------------------------------------------+
| 195 | 152 | 0 | 554 | Description 1  | 2013 | 3677 | 4187 | 3344 | 4001 | 4966 | 1079 | 452 | 2224 | 45478 | 2104  | 122 | 110 |
+--------------------------------------------------------------------------------------------------------------------------------+
| 195 | 152 | 0 | 554 | Description 1  | 2013 | 3377 | 4187 | 3344 | 4001 | 4966 | 1076 | 452 | 2224 | 45478 | 21554 | 122 | 110 |
+--------------------------------------------------------------------------------------------------------------------------------+

这样的事情是否可能?

我读过关于数据透视表的内容,这似乎与我想要做的类似,但我没有找到任何行为类似的例子。

我该怎么做?


我尝试了什么:

WITH pivot_data AS (
  SELECT PI, VS, S, HID, DESC, MS, QT VOLUME
  FROM MONTHLY_RATES
)
SELECT *
FROM pivot_data
PIVOT (
  sum(VOLUME)
  FOR MS
  IN  (
    'JAN',
    'FEB',
    'MAR',
    'APR',
    'MAY',
    'JUN',
    'JUL',
    'AUG',
    'SEP',
    'OCT',
    'NOV',
    'DEC'
  )
);

它有效,但确实省略了年份(我需要保留),并且在重复值的情况下, 总结 每月的值,这不是我想要的是什么。

更新

MONTHLY_RATES表:

CREATE TABLE MONTHLY_RATES (
  PI   VARCHAR2(3 CHAR), 
  VS   VARCHAR2(3 CHAR),  
  S    VARCHAR2(2 CHAR),  
  HID  VARCHAR2(3 CHAR),  
  "DESC" VARCHAR2(200 CHAR),  
  MS   VARCHAR2(4 CHAR),  
  QT   NUMBER(10,0)
);

INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', '2013', null);
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'JAN', '3677');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'FEB', '4187');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'MAR', '3344');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'APR', '4001');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'MAY', '4966');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'JUN', '1079');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'JUL', '452');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'AUG', '2224');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'SEP', '45478');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'OCT', '2104');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'NOV', '122');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'DEC', '110');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', '2013', null);
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'JAN', '3377');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'FEB', '4187');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'MAR', '3344');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'APR', '4001');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'MAY', '4966');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'JUN', '1076');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'JUL', '452');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'AUG', '2224');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'SEP', '45478');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'OCT', '21554');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'NOV', '122');
INSERT INTO MONTHLY_RATES VALUES('195', '152', '0', '554', 'Description 1', 'DEC', '110');

2 个答案:

答案 0 :(得分:0)

看看这个:

with t as (
    SELECT PI, MS,VS,S,HID,"DESC", qt
         , case when qt is null and REGEXP_LIKE(ms, '^20') then to_number(ms, '9999') end yr, rownum rn
      FROM MONTHLY_RATES
), t1 as (
    SELECT PI, MS,VS,S,HID,"DESC", qt
         , case when yr is not null then yr 
                    else lag(yr, mod(rn - 1,13)) over(order by rn) 
               end yr
             , 'G' || trunc((rn-1)/13)  grp
      FROM t
)
select distinct f.* from
(SELECT *
  FROM t1
 PIVOT (
        max(qt)
        FOR MS IN  ('JAN','FEB','MAR','APR','MAY ','JUN ','JUL ','AUG ','SEP ','OCT ','NOV ','DEC ')
       ))f

PI  VS  S  HID DESC                    YR GRP      'JAN'      'FEB'      'MAR'      'APR'
--- --- -- --- --------------- ---------- --- ---------- ---------- ---------- ----------
195 152 0  554 Description 1         2013 G1        3377       4187       3344       4001
195 152 0  554 Description 1         2014 G2        3377       4187       3344       4001
195 152 0  554 Description 1         2013 G0        3677       4187       3344       4001

我减少了结果输出,因此其中没有一堆月份。

SQLFiddle

答案 1 :(得分:-2)

检查这是否对您有所帮助:

带有年度条件的最终决定信息http://sqlfiddle.com/#!4/e3047/2

WITH pivot_data AS
(
  SELECT MTEMP1.*, MTEMP2.YEARR FROM
 ( SELECT M1.*, 'G' || TRUNC((ROWNUM-1)/13) AS GROUP_ID FROM 
 MYTABLE M1
 ) MTEMP1
 JOIN
  ( SELECT M2.MS YEARR, 'G' || (ROWNUM-1) AS GROUP_ID FROM MYTABLE M2 WHERE REGEXP_LIKE (M2.MS,'^20') 

   ) MTEMP2
 ON MTEMP1.GROUP_ID = MTEMP2.GROUP_ID

)

SELECT *
FROM pivot_data
PIVOT (
  sum(QT)
  FOR MS
  IN  (     'JAN',        'FEB',        'MAR',        'APR',        'MAY',
            'JUN',        'JUL',        'AUG',        'SEP',        'OCT',
            'NOV',        'DEC'
      )
);

WITH pivot_data AS

(SELECT M1.*, 'G' || TRUNC((ROWNUM-1)/13) AS GROUP_ID FROM MYTABLE M1)

SELECT *
FROM pivot_data
PIVOT (
  sum(QT)
  FOR MS
  IN  (     'JAN',        'FEB',        'MAR',        'APR',        'MAY',
            'JUN',        'JUL',        'AUG',        'SEP',        'OCT',
            'NOV',        'DEC'
      )
);

原帖:http://sqlfiddle.com/#!4/46263/8 这里更新了FIDDLE处理超过26条记录* http://sqlfiddle.com/#!4/6ecc9/12 *

由于您没有可以对记录进行分组的列,但是您确定每个记录只有13条记录,我正在创建一个临时字段调用GROUP_ID,它将每组记录分类为单独的组。当您为该组应用数据透视表时,您将获得所需的结果。