国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Oracle - Oracle實現行列轉換的方法分析

Oracle實現行列轉換的方法分析

2019-12-30 14:53sir Oracle

這篇文章主要介紹了Oracle實現行列轉換的方法,結合實例形式分析了Oracle針對固定列、不定列、列數不固定等情況下的行列轉換操作技巧,需要的朋友可以參考下

本文實例講述了Oracle實現行列轉換的方法。分享給大家供大家參考,具體如下:

1、固定列數的行列轉換

如:

?
1
2
3
4
5
6
7
8
9
student subject grade
--------- ---------- --------
student1 語文 80
student1 數學 70
student1 英語 60
student2 語文 90
student2 數學 80
student2 英語 100
……

轉換為:

?
1
2
3
4
語文 數學 英語
student1 80 70 60
student2 90 80 100
……

語句如下:

?
1
2
3
4
5
6
select student,
sum(decode(subject,'語文', grade,null)) "語文",
sum(decode(subject,'數學', grade,null)) "數學",
sum(decode(subject,'英語', grade,null)) "英語"
from table
group by student;

2、不定列行列轉換

如:

?
1
2
3
4
5
6
7
8
9
c1 c2
--- -----------
1 我
1 是
1 誰
2 知
2 道
3 不
……

轉換為

?
1
2
3
1 我是誰
2 知道
3 不

這一類型的轉換可以借助于PL/SQL來完成,這里給一個例子

?
1
2
3
4
5
6
7
8
9
10
11
12
CREATE OR REPLACE FUNCTION get_c2(tmp_c1 NUMBER)
RETURN VARCHAR2
IS
Col_c2 VARCHAR2(4000);
BEGIN
FOR cur IN (SELECT c2 FROM t WHERE c1=tmp_c1) LOOP
Col_c2 := Col_c2||cur.c2;
END LOOP;
Col_c2 := rtrim(Col_c2,1);
RETURN Col_c2;
END;
select distinct c1 ,get_c2(c1) cc2 from table;

或者不用pl/sql,利用分析函數和 CONNECT_BY 實現:

?
1
2
3
4
5
6
7
SELECT c1, SUBSTR (MAX (SYS_CONNECT_BY_PATH (c2, ';')), 2) NAME
  FROM (SELECT c1, c2, rn, LEAD (rn) OVER (PARTITION BY c1 ORDER BY rn) rn1
      FROM (SELECT c1, c2, ROW_NUMBER () OVER (ORDER BY c2) rn
          FROM t))
START WITH rn1 IS NULL
CONNECT BY rn1 = PRIOR rn
GROUP BY c1;

3、列數不固定(交叉表行列轉置)

這種是比較麻煩的一種,需要借助pl/sql:

原始數據:

?
1
2
3
4
5
6
7
CLASS1   CALLDATE     CALLCOUNT
1     2005-08-08    40
1     2005-08-07    6
2     2005-08-08    77
3     2005-08-09    33
3     2005-08-08    9
3     2005-08-07    21

轉置后:

?
1
2
3
4
5
CALLDATE   CallCount1 CallCount2 CallCount3
------------ ---------- ---------- ----------
2005-08-09  0     0     33
2005-08-08  40     77     9
2005-08-07 6 0     21

試驗如下:

1). 建立測試表和數據

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE t(
  class1 VARCHAR2(2 BYTE),
  calldate DATE,
  callcount INTEGER
);
INSERT INTO t(class1, calldate, callcount)
VALUES ('1', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 40);
INSERT INTO t(class1, calldate, callcount)
VALUES ('1', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 6);
INSERT INTO t(class1, calldate, callcount)
VALUES ('2', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 77);
INSERT INTO t(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/09/2005', 'MM/DD/YYYY'), 33);
INSERT INTO t(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 9);
INSERT INTO t(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 21);
COMMIT ;

2). 建立ref cursor準備輸出結果集

?
1
2
3
4
CREATE OR REPLACE PACKAGE pkg_getrecord
IS
  TYPE myrctype IS REF CURSOR;
END pkg_getrecord;

3). 建立動態(tài)sql交叉表函數,輸出結果集

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
CREATE OR REPLACE FUNCTION fn_rs
  RETURN pkg_getrecord.myrctype
IS
  s VARCHAR2 (4000);
  CURSOR c1 IS
  SELECT ',sum(case when Class1='
      || class1
      || ' then CallCount else 0 end)'
      || ' "CallCount'
      || class1
      || '"' c2
  FROM t
  GROUP BY class1;
  r1 c1%ROWTYPE;
  list_cursor pkg_getrecord.myrctype;
BEGIN
  s := 'select CallDate ';
  OPEN c1;
  LOOP
    FETCH c1 INTO r1;
    EXIT WHEN c1%NOTFOUND;
    s := s || r1.c2;
  END LOOP;
  CLOSE c1;
  s := s || ' from T group by CallDate order by CallDate desc ';
  OPEN list_cursor FOR s;
  RETURN list_cursor;
END fn_rs;

4). 測試在sql plus下執(zhí)行:

?
1
2
3
4
5
6
7
8
var results refcursor;
exec :results := fn_rs;
print results;
CALLDATE    CallCount1 CallCount2 CallCount3
--------------- ---------- ---------- ----------
2005-08-09   0     0     33
2005-08-08   40     77     9
2005-08-07   6     0     21

說明:decode

DECODE(value, if1, then1, if2,then2, if3,then3, . . . else )

Value 代表某個表的任何類型的任意列或一個通過計算所得的任何結果。當每個value值被測試,如果value的值為if1,Decode 函數的結果是then1;如果value等于if2,Decode函數結果是then2;等等。事實上,可以給出多個if/then 配對。如果value結果不等于給出的任何配對時,Decode 結果就返回else 。

另外,還可以用decoder函數來比較大小,如下:

select decode(sign(變量1-變量2),-1,變量1,變量2) from dual; --取較小值

sign()函數根據某個值是0、正數還是負數,分別返回0、1、-1

例如:

變量1=10,變量2=20

則sign(變量1-變量2)返回-1,decode解碼結果為“變量1”,達到了取較小值的目的。

希望本文所述對大家Oracle數據庫程序設計有所幫助。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 久久精品二区 | 青青久草 | 中文字幕在线观看 | 精品无码三级在线观看视频 | 欧美日韩中文字幕在线 | 国产一区二区资源 | 亚洲一区国产 | 激情久久久久 | 91亚洲国产精品 | 香蕉av777xxx色综合一区 | av在线一区二区 | 欧美亚洲一区二区三区 | 亚洲精品一区二区三区樱花 | 中文在线一区 | 亚洲九九 | 国产剧情一区二区 | 亚洲在线视频播放 | 成人精品三级av在线看 | 久久艹精品 | 成人福利网站 | 国产精品久久久久久久久久久久久久 | 中文字幕乱码亚洲精品一区 | 久久精品91久久久久久再现 | 亚洲大片| 国产日韩欧美 | 亚洲精品免费在线观看视频 | 亚洲成年人影院 | 亚洲综合视频在线观看 | 欧美日韩综合精品 | 亚州av影院 | 另类五月| 国产高清av在线播放 | 亚洲成人精品在线观看 | 免费看一区二区三区 | 亚洲精品一二三 | 99久久99久久久精品色圆 | 看a网站| 精品久久久久久久久久久久久久久久久久 | 中文字幕二区 | 午夜午夜精品一区二区三区文 | 国产成人精品久久二区二区91 |