使用 LISTAGG 或其他连接函数连接两个表

Join two tables using LISTAGG or other concatenation functions

我有以下两个table:

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

我需要使用 LISTAGG 函数或其他一些串联函数将两个 table 连接在一起,以在一行中输出 "Countries" 的值。

我当前的查询如下所示:

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 ");

我一直收到 "ORA-00979: not a GROUP BY expression" 错误

所有列(未包含在 LISTAGG 中)应在 GROUP BY 子句中:s.id, s.subject_id, s.first_name, s.last_name

您按 t_subject.id 分组并期望能够 select 所有功能相关的列,例如 t_subject.first_namet_subject.last_name。根据 SQL 标准,这是有效的。

但是,Oracle 不符合此处的标准,它要求您在 GROUP BY 子句中明确命名您想要 select 未聚合的所有列。

group by s.id, s.subject_id, s.first_name, s.last_name

应该可以解决这个问题。

另一种解决方案是在加入之前进行聚合:

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;