一、行变列1.创建测试表test,并初始化实验数据sec@ora10g> create table test (name_id varchar2(10), name varchar2(10));
sec@ora10g> insert into test values ('01','Andy1');
sec@ora10g> insert into test values ('01','Andy2');
sec@ora10g> insert into test values ('01','Andy3');
sec@ora10g> insert into test values ('01','Andy4');
sec@ora10g> insert into test values ('02','Steven1');
sec@ora10g> insert into test values ('02','Steven2');
sec@ora10g> insert into test values ('02','Steven3');
sec@ora10g> insert into test values ('02','Steven4');
sec@ora10g> commit;
2.查看测试表数据
sec@ora10g> select * from test order by name_id;
NAME_ID NAME
---------- ----------------------------------------
01 Andy1
01 Andy4
01 Andy3
01 Andy2
02 Steven1
02 Steven4
02 Steven3
02 Steven2
8 rows selected.
3.我们按照name_id不同值将该表横向转换如下
SELECT t1.name_id,
SUBSTR (MAX (SYS_CONNECT_BY_PATH (t1.NAME, ';')), 2) NAME
FROM (SELECT a.name_id, a.NAME,
ROW_NUMBER () OVER (PARTITION BY a.name_id ORDER BY a.NAME) rn
FROM TEST a) t1
START WITH t1.rn = 1
CONNECT BY t1.name_id = PRIOR t1.name_id AND t1.rn - 1 = PRIOR t1.rn
GROUP BY t1.name_id;
NAME_ID NAME
---------- ----------------------------------------
01 Andy1;Andy2;Andy3;Andy4
02 Steven1;Steven2;Steven3;Steven4
该条SQL语句的编写思想是:
1)根据分组后的行号,构造一棵树(或者多棵)。
2)把从根到叶子的值串接起来。
二、列变行
1.重新构造测试表test,并初始化实验数据
sec@ora10g> drop table test purge;
sec@ora10g> create table test (name_id varchar2(10), name varchar2(40));
sec@ora10g> insert into test values ('01','Andy1;Andy2;Andy3;Andy4');
sec@ora10g> insert into test values ('02','Steven1;Steven2;Steven3;Steven4');
sec@ora10g> commit;
2.查看测试表数据
sec@ora10g> select * from test;
NAME_ID NAME
---------- ----------------------------------------
01 Andy1;Andy2;Andy3;Andy4
02 Steven1;Steven2;Steven3;Steven4
3.行变列转换的SQL语句如下
SELECT t.name_id,
SUBSTR (t.name,
INSTR (';' t.name, ';', 1, rn),
INSTR (t.name ';', ';', 1, rn)
- INSTR (';' t.name, ';', 1, rn)
) name
FROM (SELECT a.name_id, a.name, b.rn
FROM test a,
(SELECT ROWNUM rn
FROM DUAL
CONNECT BY ROWNUM <= 100) b
WHERE INSTR (';' a.name, ';', 1, rn) > 0) t
ORDER BY 1, 2;
NAME_ID NAME
---------- ----------------------------------------
01 Andy1
01 Andy2
01 Andy3
01 Andy4
02 Steven1
02 Steven2
02 Steven3
02 Steven4
8 rows selected.
该条SQL语句的编写思想
1)构造虚拟表把源数据的行数增加
2)根据行号选择显示字段的不同部分
--转自