亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Oracle > 正文

Oracle 多行記錄合并/連接/聚合字符串的幾種方法

2024-08-29 13:55:03
字體:
來源:轉載
供稿:網友
什么是合并多行字符串(連接字符串)呢,例如:
SQL> desc test;
Name Type Nullable Default Comments
------- ------------ -------- ------- --------
COUNTRY VARCHAR2(20) Y
CITY VARCHAR2(20) Y

SQL> select * from test;


COUNTRY CITY
-------------------- --------------------
中國 臺北
中國 香港
中國 上海
日本 東京
日本 大阪
要求得到如下結果集:
------- --------------------
中國 臺北,香港,上海
日本 東京,大阪
實際就是對字符實現一個聚合功能,我很奇怪為什么Oracle沒有提供官方的聚合函數來實現它呢:)
下面就對幾種經常提及的解決方案進行分析(有一個評測標準最高★★★★★):
1.被集合字段范圍小且固定型 靈活性★ 性能★★★★ 難度 ★
這種方法的原理在于你已經知道CITY字段的值有幾種,且還不算太多,如果太多這個SQL就會相當的長。??蠢樱?
SQL> select t.country,
2 MAX(decode(t.city,'臺北',t.city||',',NULL)) ||
3 MAX(decode(t.city,'香港',t.city||',',NULL))||
4 MAX(decode(t.city,'上海',t.city||',',NULL))||
5 MAX(decode(t.city,'東京',t.city||',',NULL))||
6 MAX(decode(t.city,'大阪',t.city||',',NULL))
7 from test t GROUP BY t.country
8 /


COUNTRY MAX(DECODE(T.CITY,'臺北',T.CIT
-------------------- ------------------------------
中國 臺北,香港,上海,
日本 東京,大阪,
大家一看,估計就明白了(如果不明白,好好補習MAX DECODE和分組)。這種方法無愧為最笨的方法,但是對某些應用來說,最有效的方法也許就是它。
2.固定表固定字段函數法 靈活性★★ 性能★★★★ 難度 ★★
此法必須預先知道是哪個表,也就是說一個表就得寫一個函數,不過方法1的一個取值就要便捷多了。在大多數應用中,也不會存在大量這種合并字符串的需求。廢話完畢,看下面:
定義一個函數
create or replace function str_list( str_in in varchar2 )--分類字段
return varchar2
is
str_list varchar2(4000) default null;--連接后字符串
str varchar2(20) default null;--連接符號
begin
for x in ( select TEST.CITY from TEST where TEST.COUNTRY = str_in ) loop
str_list := str_list || str || to_char(x.city);
str := ', ';
end loop;
return str_list;
end;
使用:
SQL> select DISTINCT(T.country),list_func1(t.country) from test t;

COUNTRY LIST_FUNC1(T.COUNTRY)
-------------------- ----------------
中國 臺北, 香港, 上海
日本 東京, 大阪

SQL> select t.country,str_list(t.country) from test t GROUP BY t.country;


COUNTRY STR_LIST(T.COUNTRY)
-------------------- -----------------------
中國 臺北, 香港, 上海
日本 東京, 大阪
這個時候,使用分組和求唯一都可以滿足要求。它的原理就是,根據唯一的分組字段country,在函數里面再次查詢該字段對應的所有被合并列,使用PL/SQL將其合并輸出。
3.靈活表函數法 靈活性★★★ 性能★★★ 難度 ★★★
該方法是在方法2的基礎上,使用動態SQL,將表名和字段名稱傳入,從而達到靈活的目的。
create or replace function str_list2( key_name in varchar2,
key in varchar2,
coname in varchar2,
tname in varchar2 )
return varchar2
as
type rc is ref cursor;
str varchar2(4000);
sep varchar2(2);
val varchar2(4000);
cur rc;
begin
open cur for 'select '||coname||'
from '|| tname || '
where ' || key_name || ' = :x '
using key;
loop
fetch cur into val;
exit when cur%notfound;
str := str || sep || val;
sep := ', ';
end loop;
close cur;
return str;
end;
SQL> select test.country,
2 str_list2('COUNTRY', test.country, 'CITY', 'TEST') emplist
3 from test
4 group by test.country
5 /


COUNTRY EMPLIST
-------------------- -----------------
中國 臺北, 香港, 上海
日本 東京, 大阪
4.一條SQL法 靈活性★★★★ 性能★★ 難度 ★★★★
一條SQL的法則是某位大師提出的,大家曾經在某個時期都樂此不彼的尋求各種的問題一條SQL法,但是大師的意思似乎被曲解,很多性能差,可讀性差,靈活差的SQL都是這個原則產物,所謂畫虎不成反成犬類。不過,解決問題始終是第一原則,這里還是給出一個比較有代表性的一條SQL方法。
SELECT country,max(substr(city,2)) city
FROM
(SELECT country,sys_connect_by_path(city,',') city
FROM
(SELECT country,city,country||rn rchild,country||(rn-1) rfather
FROM
(SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER BY test.city) rn FROM test))
CONNECT BY PRIOR rchild=rfather START WITH rfather LIKE '%0')
GROUP BY country;
下面分步解析,有4個FROM,就有4次結果集的操作。
step 1 給記錄加上序號rn
SQL> SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER BY test.city) rn
2 FROM test
3 /


COUNTRY CITY RN
-------------------- -------------------- ----------
日本 大阪 1
日本 東京 2
中國 上海 1
中國 臺北 2
中國 香港 3
step 2 創造子節點父節點
SQL> SELECT country,city,country||rn rchild,country||(rn-1) rfather
2 FROM
3 (SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER BY test.city) rn
4 FROM test)
5 /
日本 大阪 日本1 日本0
日本 東京 日本2 日本1
中國 上海 中國1 中國0
中國 臺北 中國2 中國1
中國 香港 中國3 中國2
step 3 利用sys_connect_by_path生成結果集
SELECT country,sys_connect_by_path(city,',') city
FROM
(SELECT country,city,country||rn rchild,country||(rn-1) rfather
FROM
(SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER BY test.city) rn FROM test)) CONNECT BY PRIOR rchild=rfather START WITH rfather LIKE '%0'
日本 ,大阪
日本 ,大阪,東京
中國 ,上海
中國 ,上海,臺北
中國 ,上海,臺北,香港
step 4 最終步驟,篩選結果集合
SQL> SELECT country,max(substr(city,2)) city
2 FROM
3 (SELECT country,sys_connect_by_path(city,',') city
4 FROM
5 (SELECT country,city,country||rn rchild,country||(rn-1) rfather
6 FROM
7 (SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER BY test.city) rn
8 FROM test))
9 CONNECT BY PRIOR rchild=rfather START WITH rfather LIKE '%0')
10 GROUP BY country;


COUNTRY CITY
-------------------- -------
中國 上海,臺北,香港
日本 大阪,東京


可謂是,7歪8搞,最后還是弄出來了,呵呵。 PS:(邏輯上是對的..但是寫的比較繁瑣,可以簡化!)
5.自定義聚合函數 靈活性★★★★★ 性能★★★★★ 難度 ★★★★★
最后一個方法是我認為“王道”的方法,自定義聚合函數。
就如何我在本開始說的,為啥oracle沒有這種聚合函數呢?我也不知道,但oracle提供了聚合函數的API可以讓我方便的自己定義聚合函數。
詳細可以看Oracle Data Catridge guide這個文檔。連接如下:

下面給出一個簡單的例子:
SQL> SELECT t.country,strcat(t.city) FROM test t GROUP BY t.country;


COUNTRY STRCAT(T.CITY)
-------------------- ------------------
日本 東京,大阪
中國 臺北,香港,上海
簡單吧,和官方的函數一樣的便捷高效。
函數:
CREATE OR REPLACE FUNCTION strcat(input varchar2 )
RETURN varchar2
PARALLEL_ENABLE AGGREGATE USING strcat_type;
TYPE:
create or replace type strcat_type as object (
cat_string varchar2(4000),
static function ODCIAggregateInitialize(cs_ctx In Out strcat_type) return number,
member function ODCIAggregateIterate(self In Out strcat_type,value in varchar2) return number,
member function ODCIAggregateMerge(self In Out strcat_type,ctx2 In Out strcat_type) return number,member function ODCIAggregateTerminate(self In Out strcat_type,returnValue Out
varchar2,flags in number) return number)
6.待發掘...

PS: 在 oracle 10g下,可以使用以下系統函數:
select id,WMSYS.WM_CONCAT(oid) oid
from table1
group by id
總結,合并字符串還有更多的方法希望大家能發掘,本文的目的主要是拋磚引玉,如果有新的發現我會繼續更新方法。需要注意的問題是,本文采用varchar2為例子,所以長度有限制,oracle的版本對方法的實現也影響。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产精品大全| 成人欧美一区二区三区黑人| 亚洲新中文字幕| 国产午夜精品一区理论片飘花| 欧美激情日韩图片| 国产裸体写真av一区二区| 国产福利精品av综合导导航| 亚洲日韩欧美视频| 91av中文字幕| 国产成+人+综合+亚洲欧美丁香花| 亚洲欧洲一区二区三区在线观看| 国产精品嫩草视频| 秋霞成人午夜鲁丝一区二区三区| 日韩高清av一区二区三区| 精品久久久久久久久国产字幕| 亚州国产精品久久久| 亚洲一区二区三区视频| 国产精品亚洲自拍| 亚洲经典中文字幕| 国产精品999| 国产精品爽爽ⅴa在线观看| 欧美午夜久久久| 国产99久久久欧美黑人| 色伦专区97中文字幕| 国产精品久久久久不卡| 国产极品jizzhd欧美| 亚洲精品视频免费在线观看| 最近免费中文字幕视频2019| 久久综合色影院| 亚洲欧美自拍一区| 福利二区91精品bt7086| 国产精品久久久久7777婷婷| 国产精品劲爆视频| 视频在线观看一区二区| 久久亚洲国产成人| 成人久久18免费网站图片| 91视频免费在线| 久久亚洲精品网站| 亚洲国产欧美一区二区丝袜黑人| 欧美精品性视频| 日韩69视频在线观看| 国产欧美一区二区三区久久| 不卡中文字幕av| 中文字幕日韩精品在线| 久久久免费观看| 欧美精品一本久久男人的天堂| 91日韩在线播放| 久久人91精品久久久久久不卡| 久久亚洲综合国产精品99麻豆精品福利| 亚洲成人激情视频| 69影院欧美专区视频| 欧美日韩激情视频8区| 久久国产精品视频| 日韩欧美中文字幕在线播放| 伊人伊成久久人综合网站| 国产主播在线一区| 国产成人精品在线视频| 91麻豆国产精品| 久久久久女教师免费一区| 亚洲一区av在线播放| 精品自拍视频在线观看| 成人在线免费观看视视频| 欧美精品情趣视频| 久热精品视频在线观看一区| 久久久国产视频91| 亚洲欧美中文另类| 日韩电影中文字幕av| 久久久国产一区| 91九色视频在线| 欧美激情一区二区三级高清视频| 国产精品久久久久999| 国产精品成久久久久三级| 日韩成人在线视频网站| 亚洲精品久久久久久下一站| 亚洲精品国产精品国自产在线| 欧美激情啊啊啊| 亚洲精品99久久久久中文字幕| 成人黄色网免费| 亚洲一区二区三区xxx视频| 大桥未久av一区二区三区| 久久精品国产一区二区电影| 国产视频久久久久| 久久福利网址导航| 国产精品高清在线观看| 欧美日韩免费观看中文| 日韩在线中文字| 国产精品自在线| 亚洲女人初尝黑人巨大| 国产99久久精品一区二区 夜夜躁日日躁| 日韩欧美a级成人黄色| 国产一区二区三区免费视频| 中文字幕亚洲欧美日韩在线不卡| 国产精品av免费在线观看| 欧美日韩亚洲精品一区二区三区| 亚洲精品乱码久久久久久金桔影视| 91国偷自产一区二区三区的观看方式| 在线视频精品一| 26uuu另类亚洲欧美日本一| 亚洲欧洲一区二区三区久久| 6080yy精品一区二区三区| 日韩精品小视频| 国产精品久久久久久久美男| 欧美亚洲午夜视频在线观看| 国产成人一区三区| 国产精品美女主播在线观看纯欲| 国产精品免费一区豆花| 成人黄色av播放免费| 国产精品免费久久久| 色哟哟亚洲精品一区二区| 热99久久精品| 国产一区二区美女视频| 国产视频精品自拍| 92国产精品久久久久首页| 国产精品日韩在线一区| 亚洲欧美另类国产| 亚洲图片欧美午夜| 日韩一区二区欧美| 91精品国产综合久久香蕉| 亚洲国产精品成人一区二区| 国产精品v日韩精品| 一本色道久久88综合日韩精品| 欧美成人午夜激情在线| 国产一区二区三区四区福利| 亚洲高清一二三区| 日韩在线观看免费全| 久久久最新网址| 91国内揄拍国内精品对白| 午夜精品理论片| 亚洲一区二区三区四区在线播放| 欧美精品激情在线| 欧美福利视频网站| 国产成人福利视频| 国产日本欧美视频| 黄色成人在线免费| 日日狠狠久久偷偷四色综合免费| 亚洲欧美国产精品久久久久久久| 原创国产精品91| 国产中文字幕日韩| 精品无人区乱码1区2区3区在线| 欧美视频一区二区三区…| 久久天天躁狠狠躁夜夜躁| 俺也去精品视频在线观看| 人人澡人人澡人人看欧美| 亚洲人精品午夜在线观看| 日本欧美黄网站| 久久香蕉国产线看观看av| 欧日韩在线观看| 欧洲s码亚洲m码精品一区| 日韩精品在线视频美女| 国a精品视频大全| 久久中文久久字幕| 成人妇女淫片aaaa视频| 国产精品美女999| 懂色aⅴ精品一区二区三区蜜月| 97久久超碰福利国产精品…| 懂色av影视一区二区三区| 日韩大陆欧美高清视频区| 国产香蕉一区二区三区在线视频| 日韩精品极品毛片系列视频| 懂色av中文一区二区三区天美| 日韩av资源在线播放| 欧美性猛交xxxx富婆| 日韩欧美在线国产| 国产美女高潮久久白浆|