Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            302 隨筆 :: 26 文章 :: 82 評(píng)論 :: 0 Trackbacks

          create table t8 (i int ,a number ,b varchar2 ( 20 ));

          ?

          insert into ? t8 values ( 1 , 2 , 'c' );

          insert into ? t8 values ( 1 , 3 , 'x' );

          insert into ? t8 values ( 1 , 4 , 'b' );

          insert into ? t8 values ( 2 , 5 , 'd' );

          insert into ? t8 values ( 2 , 6 , 'h' );

          insert into ? t8 values ( 3 , 7 , 'j' );

          insert into ? t8 values ( 3 , 8 , 'y' );

          insert into ? t8 values ( 3 , 9 , 'l' );

          insert into ? t8 values ( 3 , 10 , 'v' );

          ?

          commit ;

          ?

          SQL> select * from t8;

          ?

          ???????? I????????? A B

          ---------- ---------- --------------------

          ???????? 1????????? 2 c

          ???????? 1????????? 3 x

          ???????? 1????????? 4 b

          ???????? 2????????? 5 d

          ???????? 2????????? 6 h

          ???????? 3????????? 7 j

          ???????? 3????????? 8 y

          ???????? 3????????? 9 l

          ???????? 3???????? 10 v

          ?

          已選擇 9 行。

          ?

          ?

          希望得到的結(jié)果:

          ?

          I???? CHAR

          ---------- ----------

          1?? c,x,b

          2?? d,h

          3?? j,y,l,v

          ?

          ?

          ?

          方法一:

          ?

          如果是 10g ,則可使用最簡(jiǎn)單的方法:wm_sys.wm_concat函數(shù) (wm_sys 不加也可 )

          ?

          SQL> select i,wmsys.wm_concat(b) from t group by i;

          ?

          ???????? I WMSYS.WM_CONCAT(B)

          ---------- --------------------

          ???????? 1 c,x,b

          ???????? 2 d,h

          ???????? 3 j,y,l,v

          ?

          缺點(diǎn):不能加排序功能,例如按 a 列逆序排列,需要在前一層排好序之后再使用wmsys.wm_concat

          ?

          ?

          ?

          方法二:

          ?

          9i 9i 以前的數(shù)據(jù)庫(kù)版本可使用 connect by 來(lái)實(shí)現(xiàn)子葉的連接:

          ?

          select i, ltrim( max (sys_connect_by_path(b, ',' )), ',' ) b

          ? from ( select i,

          ?????????????? b,

          ?????????????? a,

          ?????????????? min (a) over( partition by i) a_min,

          ?????????????? (row_number() over( order by i, a)) +

          ?????????????? (dense_rank() over( order by i)) numid

          ????????? from t8)

          ? start with a = a_min

          connect by numid - 1 = prior numid

          ? group by i;

          ?

          ?

          解釋一下這段 SQL

          1 、最里面一層,對(duì)表 t8 進(jìn)行處理,主要是列出了列 numid 用于等下的 connect by 操作,具體效果如下:

          ?

          SQL> select i,b,a,min(a) over(partition by i) a_min,

          ? 2? (row_number() over(order by i, a)) a,

          ? 3? (dense_rank() over(order by i)) b,

          ? 4? (row_number() over(order by i, a)) +(dense_rank() over(order by i)) numid

          ? 5? from t8;

          ?

          ?? I B?????? A????? A_MIN??? A??? B????? NUMID

          ---- ---- ---- ---------- ---- ---- ----------

          ?? 1 c ?????? 2????????? 2??? 1??? 1????????? 2

          ?? 1 x?????? 3????????? 2??? 2??? 1????????? 3

          ?? 1 b?????? 4????????? 2??? 3??? 1????????? 4

          ?? 2 d?????? 5????????? 5??? 4??? 2????????? 6

          ?? 2 h?????? 6????????? 5??? 5??? 2????????? 7

          ?? 3 j?????? 7????????? 7??? 6??? 3????????? 9

          ?? 3 y?????? 8????????? 7??? 7??? 3???????? 10

          ?? 3 l ?????? 9????? ????7??? 8??? 3???????? 11

          ?? 3 v????? 10????????? 7??? 9??? 3???????? 12

          ?

          9 rows selected

          ?

          其中 row_mun 產(chǎn)生依次列表, dense_rank 產(chǎn)生相同值相同排名,這樣通過(guò) dense_rank 就可以區(qū)分出在哪里截?cái)?/span> connect by

          numid 列可以看出,每個(gè)相同的 i 對(duì)應(yīng)一組序列,之后跳過(guò)一個(gè)數(shù)字后繼續(xù)形成序列

          ?

          2 、通過(guò) sys_connect_by_path ,以及 start with a = a_min connect by numid - 1 = prior numid 來(lái)形成一個(gè)分支列表,結(jié)果如下:

          ?

          ?? I B

          ---- --------

          ?? 1 ,c

          ?? 1 ,c,x

          ?? 1 ,c,x,b

          ?? 2 ,d

          ?? 2 ,d,h

          ?? 3 ,j

          ?? 3 ,j,y

          ?? 3 ,j,y,l

          ?? 3 ,j,y,l,v

          ?

          ?

          3 、通過(guò) max 函數(shù)選出我們需要的每個(gè) i 對(duì)應(yīng)的最后一列

          ?

          ?? I B

          ---- --------

          ?? 1 ,c,x,b

          ?? 2 ,d,h

          ?? 3 ,j,y,l,v

          ?

          4 、用 ltrim substr 來(lái)去掉最前面的 ,

          ?

          ?

          ?

          方法三:

          ?

          自己寫一個(gè)函數(shù)來(lái)處理:

          ?

          create or replace function my_concat(n number )

          return varchar2

          is

          ? type typ_cursor is ref cursor ;

          ?v_cursor typ_cursor;

          ?v_temp varchar2 ( 10 );

          ?v_result varchar2 ( 4000 ):= '' ;

          ?v_sql varchar2 ( 200 );

          begin

          ?v_sql := 'select b from t8 where i=' || n || ' order by a' ;

          ? open v_cursor for v_sql;

          ? loop

          ??? fetch v_cursor into v_temp;

          ??? exit when v_cursor % notfound ;

          ??? v_result := v_result || ',' || v_temp;

          ? end loop ;

          ? return substr(v_result, 2 );

          end ;

          ?

          ?

          SQL> select i,my_concat(i) from t8 group by i;

          ?

          ?? I MY_CONCAT(I)

          ---- --------------------------------------------------------------------------------

          ?? 1 c,x,b

          ?? 2 d,h

          ?? 3 j,y,l,v

          ?

          ?

          ?

          ?

          ?





          -The End-

          posted on 2008-09-08 17:31 decode360-3 閱讀(238) 評(píng)論(0)  編輯  收藏 所屬分類: SQL Dev
          主站蜘蛛池模板: 玛多县| 宕昌县| 城固县| 辉县市| 龙江县| 禹城市| 贵港市| 花莲县| 蕲春县| 凤凰县| 庄浪县| 临朐县| 南城县| 盐源县| 康马县| 阿合奇县| 赤峰市| 福海县| 汤原县| 榆树市| 汽车| 玉门市| 西畴县| 华池县| 潢川县| 佛学| 蓝山县| 梅河口市| 康保县| 中山市| 藁城市| 岳阳市| 绩溪县| 宝兴县| 军事| 横峰县| 卢氏县| 博湖县| 临邑县| 民权县| 万年县|