Chinaunix首页 | 论坛 | 博客
  • 博客访问: 141017
  • 博文数量: 161
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: -30
  • 用 户 组: 普通用户
  • 注册时间: 2017-09-21 21:45
文章分类
文章存档

2009年(1)

2008年(74)

2007年(48)

2006年(38)

我的朋友

分类: Oracle

2007-06-15 16:06:58

方法一:
----------------------------------------------------------------
---Muti-row to line(col2row)
----------------------------------------------------------------
create or replace type str_tab is table of varchar2(20);
/
grant all on str_tab to public;
create public synonym str_tab for str_tab;
create or replace function col2row(pv in str_tab) return varchar2
is
  ls varchar2(4000);
begin
  for i in 1..pv.count loop
    ls := ls || pv(i);
  end loop;
  return ls;
end;
/
grant execute on col2row to public;
create public synonym col2row for col2row;
----------------------------------------------------------------
--multi column,convert one column base on another column, for example
----------------------------------------------------------------
create table t(id number,name varchar2(10));
insert into t values(1,'Joan');
insert into t values(1,'Jack');
insert into t values(1,'Tom');
insert into t values(2,'Rose');
insert into t values(2,'Jenny');
---------------------------------------------------------------
SQL(c3dev)>select * from t;
        ID NAME
---------- ----------
         1 Joan
         1 Jack
         1 Tom
         2 Rose
         2 Jenny
---------------------------
--column to row
---------------------------
SQL(c3dev)>column names format a80;
SQL(c3dev)>set line 120
SQL(c3dev)>select t0.id,
  2     col2row(cast(multiset(select name from t where t.id = t0.id) as str_tab)) names
  3  from (select distinct id from t) t0;
        ID NAMES
---------- --------------------------------------------------------------------------------
         1 JoanJackTom
         2 RoseJenny

----------------------------------------------------------------
--single column,convert multil row to one row, for example
----------------------------------------------------------------
create table t1(name varchar2(20));
insert into t1 values('Chen');
insert into t1 values('Chuan');
insert into t1 values('Zhong');
SQL(c3dev)>select * from t1;
NAME
--------------------
Chen
Chuan
Zhong
---------------------------
--column to row
---------------------------
select col2row(cast(multiset(select name from t1) as str_tab)) names from t1 where rownum=1
SQL(c3dev)>select col2row(cast(multiset(select name from t1) as str_tab)) names from t1 where rownum=1;
NAMES
--------------------------------------------------------------------------------
ChenChuanZhong

--if need to add list separator
SQL(c3dev)>select col2row(cast(multiset(select name||' ' from t1) as str_tab)) names from t1 where rownum=1;
NAMES
--------------------------------------------------------------------------------
Chen  Chuan Zhong
 
方法二:
create table t2(col1 varchar2(10),col2 varchar2(10));
insert into t2 values('001','vl1');
insert into t2 values('001','vl2');
insert into t2 values('001','vl3');
insert into t2 values('002','vl1');
insert into t2 values('002','vl2');
SELECT COL1,LTRIM(MAX(SYS_CONNECT_BY_PATH(COL2,',')),',') COL2
 FROM
 (
 SELECT COL1,COL2,MIN(COL2) OVER(PARTITION BY COL1) COL2_MIN,
 (ROW_NUMBER() OVER(ORDER BY COL1,COL2))+(DENSE_RANK() OVER (ORDER BY COL1)) NUMID
 FROM T2
 )
 START WITH COL2=COL2_MIN CONNECT BY NUMID-1=PRIOR NUMID
 GROUP BY COL1;
COL1       COL2
---------- ----------------------------------------
001        vl1,vl2,vl3
002        vl1,vl2

 
 方法三(需要知道确定有几行):
 SELECT deptno, dname, emps
  FROM (SELECT d.deptno, d.dname,
               RTRIM
                  (   e.ename
                   || ', '
                   || LEAD (e.ename, 1) OVER (PARTITION BY d.deptno ORDER BY e.ename)
                   || ', '
                   || LEAD (e.ename, 2) OVER (PARTITION BY d.deptno ORDER BY e.ename)
                   || ', '
                   || LEAD (e.ename, 3) OVER (PARTITION BY d.deptno ORDER BY e.ename)
                   || ', '
                   || LEAD (e.ename, 4) OVER (PARTITION BY d.deptno ORDER BY e.ename)
                   || ', '
                   || LEAD (e.ename, 5) OVER (PARTITION BY d.deptno ORDER BY e.ename),
                   ', '
                  ) emps,
               ROW_NUMBER () OVER (PARTITION BY d.deptno ORDER BY e.ename) x
          FROM emp e, dept d
         WHERE d.deptno = e.deptno)
 WHERE x = 1
/
    DEPTNO DNAME          EMPS
---------- -------------- ----------------------------------------------------------------------
        10 ACCOUNTING     CLARK, KING, MILLER
        20 RESEARCH       ADAMS, FORD, JONES, SCOTT, SMITH
        30 SALES          ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD
 
 
 
 
 
阅读(2858) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~