This article illustrates the method of Oracle to implement row and column conversion. Share to everyone for your reference, specific as follows:
1, the row and column conversion of fixed number
Such as:
Student subject Grade
---------------------------
student1 language
student1 math student1
English
Student2 language
student2 mathematics
student2 English ...
Convert to:
Chinese maths english
student1 student2 ......
Statement as follows:
Select student,
sum (decode (subject, ' language ', grade,null)) "Language",
sum (decode (subject, ' mathematics ', Grade,null)) "Mathematics",
sum (decode (subject, ' English ', grade,null)) ' English ' from
table
Group by student;
2. Indefinite column and row conversion
Such as:
C1 C2
--------------
1 I
1 is
1 who
2 know
2 road
3 not
...
Converted to
This type of conversion can be done with the help of Pl/sql, which gives an example
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;
or without pl/sql, using analytic functions and CONNECT_BY implementations:
Select C1, SUBSTR (MAX (Sys_connect_by_path (C2, ')), 2) NAME from
(select C1, c2, RN, leads (RN) over (PARTITION by C1 ORDER by RN) Rn1
from (SELECT C1, C2, Row_number () over (the order by C2) RN from
t))-
START with RN1 is NU LL
CONNECT by rn1 = PRIOR rn
GROUP by C1;
3, the number of columns is not fixed (cross table row transpose)
This is the more troublesome one, need to rely on Pl/sql:
Raw data:
CLASS1 calldate callcount
1 2005-08-08
1 2005-08-07 6
2 2005-08-08
3 2005-08-09
3 2005-08-08 9
3 2005-08-07 21
After transpose:
Calldate CallCount1 CallCount2 CallCount3
------------------------------------------
2005-08-09 0 0
2005-08-08 9
2005-08-07 6 0 21
The experiment is as follows:
1. Establish test tables and data
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 ');
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 '), etc.
INSERT into T (Class1, Calldate, Callcount)
VALUES (' 3 ', to_date (' 08/09/2005 ', ' mm/dd/yyyy ');
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 ');
COMMIT;
2). Establish REF CURSOR prepare output result set
CREATE OR REPLACE PACKAGE pkg_getrecord
is
TYPE myrctype is REF CURSOR;
End Pkg_getrecord;
3. Establish dynamic SQL crosstab function, output result set
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). Test executed under SQL Plus:
var results refcursor;
Exec:results: = fn_rs;
Print results;
Calldate CallCount1 CallCount2 CallCount3
---------------------------------------------
2005-08-09 0 0
2005-08-08 9
2005-08-07 6 0 21
Description: Decode
DECODE (value, IF1, Then1, If2,then2, If3,then3, ... else)
Value represents any column of any type in a table, or any result that is computed. When each value is tested, if value is the result of the If1,decode function is then1, and if value equals If2,decode function The result is then2; In fact, multiple if/then pairs can be given. If the value result is not equal to any pairing given, the Decode result returns else.
In addition, you can use the decoder function to compare sizes, as follows:
Select decode (sign (variable 1-variable 2),-1, variable 1, variable 2) from dual; --Take a smaller value
The sign () function returns 0, 1, and 1, depending on whether a value is 0, positive, or negative.
For example:
Variable 1=10, variable 2=20
Then sign (variable 1-variable 2) returns the -1,decode decoding result as "Variable 1", which achieves the goal of taking a smaller value.
More readers interested in Oracle-related content can view the site topics: "Oracle Common Functions Summary", "Oracle Date and time Operation skills Summary" and "Php+oracle Database programming Skills Summary"
I hope this article will help you with your Oracle database program design.