Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of PostgreSQL's array_agg in Oracle XE 11.2 [duplicate]

I have a Oracle 11g XE database and I have a query the result set:

ID   Category
1    Cat1
1    Cat2
2    Cat3
2    Cat4

I want to get distinct id's with all related categories in same row as comma separated like this

ID   Categories
1    Cat1,Cat2
2    Cat3,Cat4

I was using Postgres before and array_agg helped me there. How can I get same result in Oracle 11g XE?

like image 776
Murmelto Avatar asked Dec 17 '17 15:12

Murmelto


People also ask

How to eliminate duplicates in LISTAGG in Oracle?

To remove the duplicates, prior to 19c, you would use a nested select to get just the unique jobs for the LISTAGG function. 4 rows selected. With 19c, you can now just use DISTINCT within your LISTAGG to remove any repeated values.

What is Array_agg?

The ARRAY_AGG() accepts an expression that returns a value of any type which is valid for an array element. The ORDER BY clause is an optional clause. It specifies the order of rows processed in the aggregation, which determines the order of the elements in the result array.


2 Answers

Unless you are using it in a stored procedure to save the output as an array(or collection), a query with LISTAGG should be sufficient and gives the same output.

select ID , LISTAGG(Category,',') WITHIN GROUP ( ORDER BY ID ) Categories
FROM yourtable GROUP BY ID;

In oracle, we do not have have a straightforward conversion function like array_agg. However, you can create a user-defined collection type, then use CAST and COLLECT functions to convert it to a NESTED TABLE to get the same desired output.

Firstly, create a collection TYPE.

create or replace TYPE categorytype as TABLE OF VARCHAR2(20);

Now, running this query is equivalent to using string_agg or LISTAGG, although categories is an array or collection, rather than a string.

select id, CAST ( COLLECT(Category) as categorytype ) categories
FROM yourtable group by id;

| ID | CATEGORIES |
|----|------------|
|  1 |  Cat1,Cat2 |
|  2 |  Cat3,Cat4 |

DEMO

like image 70
Kaushik Nayak Avatar answered Oct 17 '22 17:10

Kaushik Nayak


Oracle has a function listagg() which is pretty close to Postgres's string_agg(). Both seem to do what you want to do.

However, array_agg() creates an array using a SQL expression. I don't think Oracle supports arrays as native types in SQL statements (although arrays are part of PL/SQL). Hence there is no equivalent.

like image 25
Gordon Linoff Avatar answered Oct 17 '22 15:10

Gordon Linoff