Oracle複数行の統合/接続/統合文字列を記録するいくつかの方法


何が複数行の文字列(連結文字列)を統合しますか?例えば、SQL>desc test。Name Type Nullable Default Comments----------------------COUNTRY VRCHARR 2(20)Y CITY VRCHAR 2(20)Y SQL>select*from test;COUNTRY CITY--------------------------中国台北中国香港中国上海日本東京日本大阪は、次のような結果集を得ることを要求しています。------------------中国台北、香港、上海日本東京、大阪は実際に文字に対して重合機能を実現しています。なぜOracleが公式の集計関数を提供していないのか不思議です。以下にいくつかのよく言及されているソリューションを分析します。まだ多くはないです。このSQLが多すぎるとかなり長いです。例を見ると、SQL>select t.co.co try,2 MAX(decode(t.city,台北',t.city?;',NULL)?3MAX(decode(t.ccity,香港',t.city??;;?;;?;;;;;;;;?;;;;;;;;;;;,'''''''''''''''''''''',''''''''''''''''''''''''''''',|5 MAX(decode(t.city,東京',t.city||'、',NULL))6 MAX(decode(t.city,大阪',t.city??|',NULL)7 from test GROUTO.com‘台北’、T.C.IT--------------------------中国台北、香港、上海、日本東京、大阪、みんなは見て、すぐに分かると思います。この方法は最も愚かな方法として恥じないが、いくつかの応用において最も効果的な方法はそれかもしれない。2.固定表固定フィールド関数フレキシブル★性能★★★難易度★★この方法はどの表か前もって知っておく必要があります。つまり、一つの表には関数が書かれていますが、1つの値を取るには便利です。ほとんどの応用においては、このような結合文字列の大量の需要もない。無駄話は終わりました。次を見てください。関数create or replace function strを定義します。リストin varrhar 2)--分類フィールドreturn varrhar 2 is strlist varrcal 2(4000)default null;接続後の文字列str varrhar 2(20)default null;接続記号begin for x in(select TEST.City from TEST where TEST.C.OUTRY=strin)loop str_リスト:=str_list??str 124124; to_char(x.city)str:=',';end loop;return strリストend;使用:SQL>select DISTINCT(T.com untry)、list_Funnc 1(t.co untry)from test;COUNTRY LIST_FUNC 1(T.C.OUTRY)----------------------------------中国台北、香港、上海日本東京、大阪SQL>selectt.com.com untry、strulist(t.co untry)from test t GROUT BY t.com.com try;COUNTRY STR_LIST(T.C.OUTRY)-------------------------------------------中国台北、香港、上海日本東京、大阪のこの時、グループを使ってと唯一要求を満たすことができます。この原理は、唯一のパケットフィールドcountryに従って、このフィールドに対応するすべての結合された列を関数内で再度照会し、PL/SQLを用いてそれらを統合して出力することである。3.ダイナミックSQLを使用して、表名とフィールド名を入力し、柔軟な目的を達成します。create or replace function str ulist 2(key_)name in varrhar 2、key in varhar 2、coname in varrhar 2、tname in varhar 2)return varcar 2 as type rc is ref cursor;str varrrchar 2(4000)sep varrhar 2(2)val varrrhar 2(4000)cur rc;begin open cur for'select'??coname??from'?tname??||?|?key|name 124=: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.com untry,2 str_list 2('COUNTRY'、test.co untry、'CITY'、'TEST')empplist 3 from test 4 group by test.com 5/COUNTRY EMPLIST-----------------------------------中国台北、香港、上海日本東京、大阪4.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|rnrchild,country|?(rn-1)rfather FROM(SELECT test.com,test.city,row_number()over(PATION BY test.com untry ORDER BY test.city)rn FROM test)CONNET BY PRIOR rfather START WITH rfather LIKE'%0')GROUT BY country;次のステップで解析します。4つのFROMがあり、4回の結果集の操作があります。step 1記録に番号rn SQL>SELECT test.com untryを加え、test.city,row_number()over(PARTTION BY test.com untry ORDER BY test.city)rn 2 FROM test 3/COUNTRY CITY RN----------------日本大阪1中国上海1中国台北2中国香港3 step 2創造サブノードSQL>SELECT country,citycountry?(rn-1)rfather 2 FROM 3(SELECT test.co untry,test.city,row_number()over(PATION BY test.com ORDER BY test.city)rn 4 FROM test)5/日本大阪日本1日本0日本東京日本2日本1中国上海中国1台北中国2中国1香港中国3中国2 step 3利用syss_connect()by_path生成結果集SELECT country,sys_connect()by_path(city)',')city FROM(SELECT country,city,country|rnrchild,country|?(rn-1)rfather FROM(SELECT test.com,test.city,row_number()over(PATION BY test.com untry ORDER BY test.city)rn FROM test)CONNET BY PRIOR rfather START WITH rfather LIKE'%0'日本、大阪日本、大阪、東京中国、上海、上海、台北、中国、上海、台北、香港、Qtracy2)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.com.com,test.city,row_number()over(PARTTION BY test.com untry ORDER BY test.city)9 CONNET BY PRIOR rfather START WITH rfather LIKE'%0')10 GROUT BY country;COUNTRY CITY--------------------中国上海、台北、香港日本大阪、東京は言うことができます。PS:(論理的には正しいです。でも、書くのが煩雑です。簡略化できます。)5.カスタム集計機能★フレキシブル★★性能★★難易度★★★★★★★最終的な方法は、「王道」と思う方法で、カスタマイズ集計関数です。どうやって本で話しましたが、なぜoracleにはこのような重合関数がないですか?私もよく分かりませんが、oracleは重合関数のAPIを提供してくれて、私の便利な自分で重合関数を定義できます。詳細はOracle Data Catridge guideというドキュメントを見ることができます。以下のように接続しますhttp://www.oracle.com.cn/other/9ionlinedoc/appdev.920/a96595/toc.htm 簡単な例を以下に示します。SQL>SELECT t.co.contry、stcat(t.city)FROM test GROUT BY t.com.com try。COUNTRY STRCAT----------------------日本東京、大阪中国台北、香港、上海は簡単でしょう。公式の関数と同じように便利で効率的です。関数:CREATE OR REPLACE FNCTION stracat(input varrhar 2)RETURN varch har 2 PAARALLEL_ENABLE AGGREGATE USING stracat uタイプTYPE:create or replace type stracat_type as object(cat_string varrchar 2(4000)、static function ODCIAggateInitialize(cs_ctx In Out stracat_type)return number,member function ODAggateIterate(self In Out stracat_type,value in varrhar 2)return number,member function ODAggateMerge(self In Out stracat_)type、ctx 2 In Out stracat_type)return number,member function ODCIAgregateTerminate(self In Out stracat_)type、return Value Out varrhar 2、flags in number)return number 6.発掘されています。…PS:oracle 10 gでは、以下のシステム関数:select id、WMSYS.WM_を使用できます。CONCAT(oid)oid from table 1 group by idのまとめは、文字列を結合するより多くの方法があります。この記事の目的は主にレンガを投げて玉を引くことです。新しい発見があれば、引き続き更新します。なお、本明細書ではvarrhar 2を例として採用しているので、長さに制限があり、oracleのバージョンは方法の実現にも影響を与えている。