如何使用LISTAGG从多行连接?

时间:2018-03-25 00:20:54

标签: sql oracle oracle-apex-5

我在APEX 5.0中有这些行的报告查询:

WITH inner_table AS
( select distinct 
 i.ID
,i.name
,i.lastname
,case i.gender
   when 'm' then 'Male'
   when 'f' then 'Female'
 end gender
,i.username
,b.name region
,i.address
,i.city city
,i.EMAIL
,r.name as "ROLE"
,ie.address as "region_location"
,case 
   when i.gender='m' THEN 'blue'
   when i.gender='f' THEN '#F6358A'
END i_color
,b.course as COURSE
,si.city UNIVERSITY
,case 
when i.id in (select app_user from scholarship) then 'check'
else 'close'
end as scholarship,
case
when i.id in (select ieur.app_user from ie_user_role ieur where role=4) then 'Admin'
else ''
end admin,
apex_item.checkbox(10, i.id, 'UNCHECKED onclick="highlightRow(this);"') as Del_usr
from  app_users i left join regions b on (i.region=b.id)
left join ie_user_role ur on (i.id = ur.app_user)
left join ie_roles r on(ur.role = r.id)
left join user_house uh on (i.id=uh.app_user)
left join reg_location ie on (uh.house=ie.id)
left join study_list sl on i.id = sl.insan
left join study_institute si on sl.institute = si.id
left join course c on sl.course = c.id
where i.is_active='Y'
order by
i.name,i.lastname,i.username,region, city, i.EMAIL) 
 SELECT * FROM inner_table where (scholarship = :P5_SCHOLARSHIP or :P5_SCHOLARSHIP is null)

我可能得到这样的结果:

|---------------------|------------------|-------|------------------|
|        Name         |     Lastname     |  ...  |      Course      |
|---------------------|------------------|-------|------------------|
|        Some         |       User       |  ...  | Course1          |
|---------------------|------------------|-------|------------------|
|        Some         |       User       |  ...  | Course2          |
|---------------------|------------------|-------|------------------|

但是我想在同一行中完成入伍课程,这是以前重复的,所以:

|---------------------|------------------|-------|------------------|
|        Name         |     Lastname     |  ...  |      Course      |
|---------------------|------------------|-------|------------------|
|        Some         |       User       |  ...  | Course1, Course2 |
|---------------------|------------------|-------|------------------|

我尝试使用LISTAGG,但我没有注意到我的尝试,所以不幸的是我现在无法发布。我基本上试过了:

,LISTAGG(b.course, ', ') within group (order by b.course) as COURSE

然后使用COURSE添加GROUP BY,但在这种情况下,整个查询受GROUP BY影响,我必须正确应用其他列,对吧?否则它导致" ORA-00937:不是单组组功能"。我在那里迷路了。

我试过的其他事情是使用上面有相同LISTAGG行的子查询表,并从子查询得到想要的输出,但是然后加入查询的其余部分并没有提供预期的结果。

我想在加入多个表时,我可以在这里为LISTAGG使用一些SQL帮助。

感谢。

2 个答案:

答案 0 :(得分:1)

当您使用聚合函数(将多行折叠为一个)时,您需要一个GROUP BY子句,因此您需要这样的内容:

SELECT i.username, 
       LISTAGG( c.course, ', ' ) WITHIN GROUP ORDER BY ( c.course )
  FROM app_users i
   ...
  LEFT JOIN course c on sl.course = c.id
 GROUP BY i.username

基本上,任何未被聚合的内容都需要在GROUP BY子句中。尝试一个更简单的查询,直到你掌握它,然后做你的大。

答案 1 :(得分:1)

你想要的是具有分析窗口功能的LISTAGG。然后使用distinct删除重复项。以下是我的示例结果/数据:http://sqlfiddle.com/#!4/6e8e3f/3

选择DISTINCT名称,last_name,其他列, LISTAGG(课程,',')WITHIN GROUP(按课程排序)          OVER(PARTITION BY name,last_name)为“Course”   FROM inner_table;