Several Methods for Oracle multi-row record merging, connection, and string Aggregation

Source: Internet
Author: User

What is a multiline string (connection string), for example:
SQL> DESC test;
Name type nullable default comments
------------------------------------------
Country varchar2 (20) y
City varchar2 (20) y

SQL> select * from test;

country city
-------------------- ------------------
Taipei, China
Hong Kong, China
Shanghai, China
Tokyo, Japan
Osaka, Japan
required result set:
------- ------------------
Chinese Taipei, Hong Kong, and Shanghai
Japan, Tokyo, and Osaka
is actually an aggregation function for characters, I am wondering why Oracle does not provide official Aggregate functions to implement it. :)
The following describes several frequently-mentioned solutions (one with the highest rating standards ).★★★★★):
1. Small set field range and fixed type flexibility★Performance★★★★Difficulty★
the principle of this method is that you already know several values of the City field, and there are not too many values. If there are too many values, this SQL statement will be quite long .. Example:
SQL> select T. country,
2 max (decode (T. city, 'taipei ', T. city | ',', null) |
3 max (decode (T. city, 'Hong Kong ', T. city | ',', null) |
4 max (decode (T. city, 'shanghai', T. city | ',', null) |
5 max (decode (T. city, 'Tokyo ', T. city | ',', null) |
6 max (decode (T. city, 'osaka ', T. city | ',', null)
7 from test T group by T. country
8/

Country max (decode (T. City, 'taipei ', T. cit
--------------------------------------------------
China's Taipei, Hong Kong, Shanghai,
Tokyo, Osaka, Japan,
You can understand it at a Glance (if you don't understand it, study Max decode and grouping well ). This method is the most stupid method, but for some applications, the most effective method may be it.
2. Fixed table fixed field Function Method flexibility★★Performance★★★★Difficulty★★
This method must know in advance which table it is, that is, a table has to write a function, but a value of method 1 is much more convenient. In most applications, there is no need to merge a large number of such strings. Go to the following link:
Define a function
Create or replace function str_list (str_in in varchar2) -- Category field
Return varchar2
Is
Str_list varchar2 (4000) default null; -- connected string
STR varchar2 (20) default null; -- Connection Symbol
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;
Usage:
SQL> select distinct (T. Country), list_func1 (T. Country) from test T;

Country list_func1 (T. Country)
------------------------------------
China's Taipei, Hong Kong, Shanghai
Tokyo, Japan, and Osaka

SQL> select T. Country, str_list (T. Country) from test T group by T. Country;

country str_list (T. country)
------------------ -----------------------
in this case, the group and request can satisfy the requirements. The principle is that, based on the unique grouping field country, all merged columns corresponding to this field are queried again in the function, and merged and output by PL/SQL.
3. Flexible Table Function Method flexibility★★★Performance★★★Difficulty★★★
Based on method 2, This method uses dynamic SQL to pass in the table name and field name for flexible purposes.
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 | '='
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
-------------------------------------
China's Taipei, Hong Kong, Shanghai
Tokyo, Japan, and Osaka
4. Flexibility of one SQL statement★★★★Performance★★Difficulty★★★★
One SQL rule was proposed by a master. in a certain period of time, everyone was happy to seek a variety of SQL methods. However, the meaning of the Master seems to be misinterpreted, and many of them have poor performance, poor readability and poor flexibility are the results of this principle. However, solving the problem is always the first principle. Here is a representative SQL method.
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;
In the following step-by-step parsing, if there are 4 from, there will be 4 result set operations.
Step 1 Add the SN rn to the record
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
--------------------------------------------------
Osaka 1, Japan
Tokyo, Japan 2
China Shanghai 1
China Taipei 2
Hong Kong, China 3
Step 2 create a child node parent node
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/
Japan Osaka Japan 1 Japan 0
Tokyo Japan 2 Japan 1
China shanghai china 1 China 0
China Taipei China 2 China 1
China Hong Kong China 3 China 2
Step 3 generate a result set using 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'
Japan and Osaka
Japan, Osaka, Tokyo
China, Shanghai
China, Shanghai, and Taipei
China, Shanghai, Taipei, Hong Kong
Step 4 Final step: filter the result set
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
---------------------------
China Shanghai, Taipei, Hong Kong
Osaka, Tokyo

It can be said that, in, we finally got it, huh, huh. PS: (logically, it is correct. But it is complicated to write and can be simplified !)
5. Flexibility of custom Aggregate functions★★★★★Performance★★★★★Difficulty★★★★★
The last method is the "Wang Dao" method, which is used to customize Aggregate functions.
In this article, why does Oracle not have such aggregate functions? I don't know, But Oracle provides an aggregate function API that allows me to easily define Aggregate functions by myself.
For more information, see the Oracle Data catridge guide document. The connection is as follows:
Http://www.oracle.com.cn/other/9ionlinedoc/appdev.920/a96595/toc.htm
The following is a simple example:
SQL> select T. Country, strcat (T. City) from test T group by T. Country;

country strcat (T. city)
------------------ ----------------
Japan, Tokyo, Osaka
Chinese Taipei, Hong Kong, Shanghai
simple, just as convenient and efficient as the official functions.
function:
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 odciaggresponinitialize (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 odciaggresponterminate (self in out strcat_type, returnvalue out
varchar2, flags in number) return number)
6. to be explored...

PS: in Oracle 10 Gb, you can use the following system functions:
select ID, wmsys. wm_concat (OID) oId
from Table1
group by ID
In summary, there are more ways to merge strings. I hope you can explore this article, if there is a new discovery, I will continue to update the method. Note that varchar2 is used as an example in this article, so the length is limited. The Oracle version also affects the implementation of the method.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.