Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LISTAGG Query "ORA-00937: not a single-group group function" [duplicate]

Tags:

sql

oracle

I'm trying to create a join with a list of comma separated values. For example:

rule_id | attribute_id
----------------------
1       | a
1       | b
2       | c
2       | d

should be:

rule_id | attribute_id
----------------------
1       | a,b
2       | c,d

I am attempting to do so using LISTAGG. However, with the below code, I'm getting ORA-00937: not a single-group group function. I noticed a FOR PATH syntax for sql-server, but it doesn't look like that works for our configuration. Here's my query:

SELECT r.rule_id as RULE_ID, 
LISTAGG(a.ATTRIBUTE_ID, ', ') WITHIN GROUP (ORDER BY a.ATTRIBUTE_ID) "ATTR_IDS"
FROM N_RULE r, N_ATTRIBUTE a 
WHERE r.RULE_ID = a.RULE_ID 
ORDER BY r.AUDIENCE, UPPER(r.NAME);
like image 748
kb_ Avatar asked Jun 16 '14 22:06

kb_


People also ask

How do I remove duplicates in Listagg?

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.

Can we use Listagg without GROUP BY?

Usage of the LISTAGG Function There are a few ways you can use this function. If you use it without any grouping, LISTAGG operates on all rows and returns a single row. If you use it with grouping, LISTAGG operates on and returns a row for each group defined by the GROUP BY clause.

What is the use of Listagg in SQL?

The LISTAGG function is used to aggregate a set of string values within a group into a single string by appending the string-expression values based on the order that's specified in the 'WITHIN GROUP' clause. As a single-set aggregate function, LISTAGG operates on all rows and returns a single output row.

What does Listagg do in Oracle?

An Oracle LISTAGG Function is an aggregate function that returns a single row. This is used to transform data from multiple rows into a single list of values separated by a given delimiter. It operates on all rows and returns single. It returns a comma or other delimiter separatedresult set just like an excel CSV file.


1 Answers

I think for your query to work, you need to add a group by, change the order by. You should also use proper explicit join syntax:

SELECT r.rule_id as RULE_ID, 
       LISTAGG(a.ATTRIBUTE_ID, ', ') WITHIN GROUP (ORDER BY a.ATTRIBUTE_ID) as "ATTR_IDS"
FROM N_RULE r JOIN
     N_ATTRIBUTE a 
     ON r.RULE_ID = a.RULE_ID 
GROUP BY r.rule_id
ORDER BY r.rule_id;

Or, possibly you want to include other attribute in the results:

SELECT r.rule_id, r.AUDIENCE, UPPER(r.NAME) 
       LISTAGG(a.ATTRIBUTE_ID, ', ') WITHIN GROUP (ORDER BY a.ATTRIBUTE_ID) as "ATTR_IDS"
FROM N_RULE r JOIN
     N_ATTRIBUTE a 
     ON r.RULE_ID = a.RULE_ID 
GROUP BY r.rule_id, r.AUDIENCE, UPPER(r.NAME)
ORDER BY r.AUDIENCE, UPPER(r.NAME);
like image 154
Gordon Linoff Avatar answered Sep 23 '22 19:09

Gordon Linoff