oracle把多行合并成字符串,怎样将Oracle多行转换成字符串?
在做一些比較復雜的DB數據導出時,有時會要求“將不固定的多行數據組合成一個字符串返回”。
例子:ISV Portal中就遇到了類似的情況,要求對于每一個APP,返回其所屬的所有類目名稱,類目名稱之間用[,]隔開。
本文就用此例子來介紹。在具體陳述實現方案之前,我們先介紹下我們即將操作的表結構:
SQL> desc app_category_link;
Name Type Nullable Default Comments
APP_CATEGORY_LINK_ID VARCHAR2(20) 主關鍵
APP_ID VARCHAR2(20) 應用ID
APP_CATEGORY_ID VARCHAR2(20) 應用類別ID
其中字段APP_ID和APP_CATEGORY_ID是一對多關系;
對于該類型的問題,總結一下大致有如下幾種常見方案:
方案1:sys_connect_by_path + start with 。
。。 connect by 。。。 prior + 分析函數
從上面的這個公式中我們可以看出,該方案主要是通過分析函數和父子級聯查詢來完成,一般是一條SQL搞定,比較省事。首先來看幾個具體的實現SQL。
具體實現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;
具體實現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;
具體實現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;
具體實現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;
請注意看4種實現方式的區別,下面分別介紹下這4種實現方式的具體思路;
第1種實現采用了1個分析函數、2次子查詢、一個like、以及父子級聯查詢字段值連接;可以猜測下性能肯定不咋的,2次子查詢本來已經很耗時了,對查詢出來的結果集還要用like匹配,速度就更慢了,此法可以查詢到我們需要的具體數據,但是效率很低,不可取;他的實現思路是利用待查詢字段值與各APP下面各類目ID的序列值進行組合,并作為父子關系級聯的依據;
第2種實現采用了3個分析函數、1次全表掃描、以及父子級聯字段值連接;和第1種實現比較而言的話效率會高不少;他的實現思路是利用各APP對應的最小類目ID作為父子級聯的開始點,而父子級聯的依據是row_number()+dense_rank(),這樣做主要是為了避免無限循環;
第
3、4兩種實現思路基本上是一樣的,都是1個分析函數、1次全表掃描、以及父子級聯字段值連接;從代碼長度來說,比前2種實現方式簡潔了不少,思路也清晰了很多,直接利用各APP對應類目ID的序列值作為父子級聯的開始點和連接依據;但仔細看看兩者的SQL,會發現第3這種方式用到了group by子句,而第4種實現卻沒有用到,而是在where子句中添加了connect_by_isleaf = 1 的查詢條件;從性能上來看,應該是第4種實現方式更高,但他只能在10g及其以后的版本中才能使用,connect_by_isleaf 字段是10g中新提供的一個偽列,他可以用來判斷該條記錄是否是樹形記錄的葉節點,不過還在用9i版本的可能就有些可惜了;
綜合以上分析,對4種實現方案,個人推薦使用第
3、4兩種實現方式,具體哪種可以看所用oracle的版本而定,簡而言之,這種實現方式優雅、簡潔、高效;。
全部
總結
以上是生活随笔為你收集整理的oracle把多行合并成字符串,怎样将Oracle多行转换成字符串?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle_sod,oracle ge
- 下一篇: iCloud备份失败怎么办iCloud无