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);
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.
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.
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.
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With