Would it be possible to construct SQL to concatenate column values from multiple rows?
The following is an example:
Table A
PID A B C
In the select where you want your concatenation, call a SQL function.
For example:
select PID, dbo.MyConcat(PID)
from TableA;
Then for the SQL function:
Function MyConcat(@PID varchar(10))
returns varchar(1000)
as
begin
declare @x varchar(1000);
select @x = isnull(@x +',', @x, @x +',') + Desc
from TableB
where PID = @PID;
return @x;
end
The Function Header syntax might be wrong, but the principle does work.
There's also an XMLAGG
function, which works on versions prior to 11.2. Because WM_CONCAT
is undocumented and unsupported by Oracle, it's recommended not to use it in production system.
With XMLAGG
you can do the following:
SELECT XMLAGG(XMLELEMENT(E,ename||',')).EXTRACT('//text()') "Result"
FROM employee_names
What this does is
ename
column (concatenated with a comma) from the employee_names
table in an xml element (with tag E)The LISTAGG analytic function was introduced in Oracle 11g Release 2, making it very easy to aggregate strings. If you are using 11g Release 2 you should use this function for string aggregation. Please refer below url for more information about string concatenation.
http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php
String Concatenation
As most of the answers suggest, LISTAGG
is the obvious option. However, one annoying aspect with LISTAGG
is that if the total length of concatenated string exceeds 4000 characters( limit for VARCHAR2
in SQL ), the below error is thrown, which is difficult to manage in Oracle versions upto 12.1
ORA-01489: result of string concatenation is too long
A new feature added in 12cR2 is the ON OVERFLOW
clause of LISTAGG
.
The query including this clause would look like:
SELECT pid, LISTAGG(Desc, ' ' on overflow truncate) WITHIN GROUP (ORDER BY seq) AS desc
FROM B GROUP BY pid;
The above will restrict the output to 4000 characters but will not throw the ORA-01489
error.
These are some of the additional options of ON OVERFLOW
clause:
ON OVERFLOW TRUNCATE 'Contd..'
: This will display 'Contd..'
at
the end of string (Default is ...
)ON OVERFLOW TRUNCATE ''
: This will display the 4000 characters
without any terminating string.ON OVERFLOW TRUNCATE WITH COUNT
: This will display the total
number of characters at the end after the terminating characters.
Eg:- '...(5512)
'ON OVERFLOW ERROR
: If you expect the LISTAGG
to fail with the
ORA-01489
error ( Which is default anyway ).