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

时间:2018-05-07 20:50:57

标签: sql oracle concatenation jointable listagg

我有以下两个表:

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函数或其他一些连接函数将两个表连接在一起,以输出"国家"的值。在一排。

我当前的查询如下所示:

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:不是GROUP BY表达"错误

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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

但是,Oracle并不遵守此处的标准,并且要求您明确命名要在GROUP BY子句中选择未选择的所有列。

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;