Reputation:
I have the following two tables:
Subject
-----------------------------------------------
ID | SUBJECT_ID | FIRST_NAME | LAST_NAME
-----------------------------------------------
2456969 | 0002531 | Sam | White
1371093 | 0002301 | Tom | Andrew
2456840 | 0002529 | Chris | Williams
Subject Countries
--------------------------------
ID | ID_OWNER | COUNTRIES
--------------------------------
2445162 | 2444907 | 303
2457722 | 2457721 | 302
2457650 | 2457649 | 211
I need to use LISTAGG function or some other concatenation function to join the two table together to output the values for "Countries" in a single row.
My current query looks like the following:
sql.append("SELECT s.id, ");
sql.append(" s.subject_id AS subjectId, ");
sql.append(" s.first_name AS firstName, ");
sql.append(" s.last_name AS lastName, ");
sql.append(" listagg(sc.countries, ', ') within group (order by sc.countries) AS countriesOfCit ");
sql.append("FROM t_subject s ");
sql.append(" JOIN m_subject_countries sc ");
sql.append(" ON s.id = sc.id_owner ");
sql.append(" group by s.id ");
and I've been getting "ORA-00979: not a GROUP BY expression" error
Upvotes: 1
Views: 2322
Reputation: 94914
You group by t_subject.id
and expect to be able to select all functionally dependent columns, such as t_subject.first_name
and t_subject.last_name
. This is valid according to the SQL standard.
Oracle, however, doesn't comply with the standard here and requires you to explicitely name all columns in your GROUP BY
clause that you want to select unaggregated.
group by s.id, s.subject_id, s.first_name, s.last_name
should solve this issue.
Another solution is to aggregate before joining:
SELECT
s.id,
s.subject_id AS subjectId,
s.first_name AS firstName,
s.last_name AS lastName,
sc.countriesOfCit
FROM t_subject s
JOIN
(
select
id_owner,
listagg(countries, ', ') within group (order by countries) AS countriesOfCit
from m_subject_countries
group by id_owner
) sc ON sc.id_owner = s.id;
Upvotes: 0
Reputation: 142743
All columns (not contained in LISTAGG
) should be in the GROUP BY
clause: s.id, s.subject_id, s.first_name, s.last_name
Upvotes: 1