日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

oracle把多行合并成字符串,怎样将Oracle多行转换成字符串?

發(fā)布時(shí)間:2023/12/2 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 oracle把多行合并成字符串,怎样将Oracle多行转换成字符串? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在做一些比較復(fù)雜的DB數(shù)據(jù)導(dǎo)出時(shí),有時(shí)會(huì)要求“將不固定的多行數(shù)據(jù)組合成一個(gè)字符串返回”。

例子:ISV Portal中就遇到了類似的情況,要求對(duì)于每一個(gè)APP,返回其所屬的所有類目名稱,類目名稱之間用[,]隔開。

本文就用此例子來介紹。在具體陳述實(shí)現(xiàn)方案之前,我們先介紹下我們即將操作的表結(jié)構(gòu):

SQL> desc app_category_link;

Name Type Nullable Default Comments

APP_CATEGORY_LINK_ID VARCHAR2(20) 主關(guān)鍵

APP_ID VARCHAR2(20) 應(yīng)用ID

APP_CATEGORY_ID VARCHAR2(20) 應(yīng)用類別ID

其中字段APP_ID和APP_CATEGORY_ID是一對(duì)多關(guān)系;

對(duì)于該類型的問題,總結(jié)一下大致有如下幾種常見方案:

方案1:sys_connect_by_path + start with 。

。。 connect by 。。。 prior + 分析函數(shù)

從上面的這個(gè)公式中我們可以看出,該方案主要是通過分析函數(shù)和父子級(jí)聯(lián)查詢來完成,一般是一條SQL搞定,比較省事。首先來看幾個(gè)具體的實(shí)現(xiàn)SQL。

具體實(shí)現(xiàn)1:

SELECT app_id,

ltrim(max(sys_connect_by_path(app_category_id, ',')), ',') categ_ids

FROM (SELECT app_id,

app_category_id,

app_category_id || '|' || rn rchild,

app_category_id || '|' || (rn - 1) rfather

FROM (SELECT app_id,

app_category_id,

row_number() over(PARTITION BY app_id ORDER BY app_category_id) rn

FROM app_category_link))

START WITH rfather LIKE '%|0'

CONNECT BY PRIOR rchild = rfather

GROUP BY app_id;

具體實(shí)現(xiàn)2:

select app_id,

ltrim(max(sys_connect_by_path(app_category_id, ',')), ',') categ_ids

from (select t。

app_id,

t。app_category_id,

min(t。app_category_id) over(partition by app_id) categ_min,

(row_number() over(order by app_id, app_category_id)) +

(dense_rank() over(order by app_id)) numid

from app_category_link t)

start with app_category_id = categ_min

connect by numid - 1 = prior numid

group by app_id;

具體實(shí)現(xiàn)3:

select app_id,

ltrim(max(sys_connect_by_path(app_category_id, ',')), ',') categ_ids

from (select t。

app_id,

t。app_category_id,

(row_number()

over(partition by app_id order by app_category_id)) numid

from app_category_link t)

start with numid = 1

connect by numid - 1 = prior numid

and app_id = prior app_id

group by app_id;

具體實(shí)現(xiàn)4:

select app_id,

ltrim(sys_connect_by_path(app_category_id, ','), ',') categ_ids

from (select t。

app_id,

t。

app_category_id,

(row_number()

over(partition by app_id order by app_category_id)) numid

from app_category_link t)

WHERE connect_by_isleaf = 1

start with numid = 1

connect by numid - 1 = prior numid

and app_id = prior app_id;

請(qǐng)注意看4種實(shí)現(xiàn)方式的區(qū)別,下面分別介紹下這4種實(shí)現(xiàn)方式的具體思路;

第1種實(shí)現(xiàn)采用了1個(gè)分析函數(shù)、2次子查詢、一個(gè)like、以及父子級(jí)聯(lián)查詢字段值連接;可以猜測(cè)下性能肯定不咋的,2次子查詢本來已經(jīng)很耗時(shí)了,對(duì)查詢出來的結(jié)果集還要用like匹配,速度就更慢了,此法可以查詢到我們需要的具體數(shù)據(jù),但是效率很低,不可取;他的實(shí)現(xiàn)思路是利用待查詢字段值與各APP下面各類目ID的序列值進(jìn)行組合,并作為父子關(guān)系級(jí)聯(lián)的依據(jù);

第2種實(shí)現(xiàn)采用了3個(gè)分析函數(shù)、1次全表掃描、以及父子級(jí)聯(lián)字段值連接;和第1種實(shí)現(xiàn)比較而言的話效率會(huì)高不少;他的實(shí)現(xiàn)思路是利用各APP對(duì)應(yīng)的最小類目ID作為父子級(jí)聯(lián)的開始點(diǎn),而父子級(jí)聯(lián)的依據(jù)是row_number()+dense_rank(),這樣做主要是為了避免無限循環(huán);

3、4兩種實(shí)現(xiàn)思路基本上是一樣的,都是1個(gè)分析函數(shù)、1次全表掃描、以及父子級(jí)聯(lián)字段值連接;從代碼長度來說,比前2種實(shí)現(xiàn)方式簡潔了不少,思路也清晰了很多,直接利用各APP對(duì)應(yīng)類目ID的序列值作為父子級(jí)聯(lián)的開始點(diǎn)和連接依據(jù);但仔細(xì)看看兩者的SQL,會(huì)發(fā)現(xiàn)第3這種方式用到了group by子句,而第4種實(shí)現(xiàn)卻沒有用到,而是在where子句中添加了connect_by_isleaf = 1 的查詢條件;從性能上來看,應(yīng)該是第4種實(shí)現(xiàn)方式更高,但他只能在10g及其以后的版本中才能使用,connect_by_isleaf 字段是10g中新提供的一個(gè)偽列,他可以用來判斷該條記錄是否是樹形記錄的葉節(jié)點(diǎn),不過還在用9i版本的可能就有些可惜了;

綜合以上分析,對(duì)4種實(shí)現(xiàn)方案,個(gè)人推薦使用第

3、4兩種實(shí)現(xiàn)方式,具體哪種可以看所用oracle的版本而定,簡而言之,這種實(shí)現(xiàn)方式優(yōu)雅、簡潔、高效;。

全部

總結(jié)

以上是生活随笔為你收集整理的oracle把多行合并成字符串,怎样将Oracle多行转换成字符串?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。