将同一列中的两行连接成一行(Oracle);使用LISTAGG?

时间:2016-05-18 16:22:37

标签: sql oracle concatenation listagg

我在Hyperion Studio中使用Oracle。我相信它是Oracle 11,但我不确定如何检查......这对我来说都是新手,我非常非常非常新手,我道歉。

无论如何,我使用查询返回一个类列表以及教导它们的教师的名字。

出现两个问题:

  1. 教师姓名分为多个列。我使用Computed Item中的递归CONCAT轻松解决了这个问题:

    CONCAT (Request.Instructor_Last_Name,CONCAT(', ',Request.Instructor_First_Name))
    
  2. 课程可能有多名教师。我希望每个课程在结果中只有一行,所以我想我会尝试在单个连接字段中显示所有教师。
  3. 为了尝试解决第二个问题,我尝试在计算项目中一起使用LISTAGG和CONCAT:

    LISTAGG(CONCAT (Request.Instructor_Last_Name,CONCAT(', ',Request.Instructor_First_Name)), 'and ') 
    WITHIN GROUP (ORDER BY Request.Instructor_Last_Name DESC) "All Instructors"
    

    这会返回错误ORA-00937: not a single-group group function

    这让我想到了这个问题:LISTAGG Query "ORA-00937: not a single-group group function" 我尝试了解决方案的变体,没有成功。这是我尝试过的一个例子:

    LISTAGG(CONCAT (Request.Instructor_Last_Name,CONCAT(', ',Request.Instructor_First_Name)), 'and ') 
    WITHIN GROUP (ORDER BY Request.Instructor_Last_Name DESC) "All Instructors"
    FROM Request
    GROUP BY *
    

    这将返回错误:

      

    ORA-00936:缺少表达

    我也试过替换

    LISTAGG(CONCAT (Request.Instructor_Last_Name,CONCAT(', ',Request.Instructor_First_Name)), 'and ') 
    

    LISTAGG(Request.Instructor_Last_Name || ', ' || Request.Instructor_First_Name,'and ') 
    

    基于我读过的其他内容,但这似乎没有任何区别(我甚至不确定这是否会起作用)。

    这让我筋疲力尽。我确信在这一点上答案一定是因为我缺乏经验而无法解决,所以任何帮助都非常感激...

    这是一个非常简化的查询版本,使用建议的代码vkp(这些是Banner表,有些人可能认识到):

    SELECT DISTINCT 
    AL1.SFRSTCR_TERM_CODE, AL1.SFRSTCR_CRN, 
    AL3.SPRIDEN_FIRST_NAME, AL3.SPRIDEN_LAST_NAME, 
    CONCAT ((AL3.SPRIDEN_LAST_NAME),CONCAT(', ',(AL3.SPRIDEN_FIRST_NAME))),   
    select Student_Registration_CRN,
    LISTAGG((Instructor_Last_Name||', '||Instructor_First_Name), 'and '))
    WITHIN GROUP (ORDER BY Instructor_Last_Name DESC) "All Instructors"
    FROM Request
    group by Student_Registration_CRN 
    FROM SATURN.SFRSTCR AL1, SATURN.SIRASGN AL2, SATURN.SPRIDEN AL3 
    WHERE ( AL1.SFRSTCR_TERM_CODE = AL2.SIRASGN_TERM_CODE (+) 
    AND  AL1.SFRSTCR_CRN = AL2.SIRASGN_CRN (+) 
    AND  AL2.SIRASGN_PIDM = AL3.SPRIDEN_PIDM (+))  
    AND ((AL3.SPRIDEN_CHANGE_IND IS NULL AND AL1.SFRSTCR_TERM_CODE='201660'))
    

    这会产生错误:

      

    ORA-00936:缺少表达

    我已经为一些列名使用了别名,所以我尝试了没有别名的建议代码,但这似乎没有什么区别。

    我尝试使用Boneist建议的SQL,直接导入.SQL文件,而不是使用可视化构建器和计算项。这是我试图运行的:

    select distinct
       al1.sfrstcr_term_code,
       al1.sfrstcr_crn,
       al3.spriden_first_name,
       al3.spriden_last_name,
       al3.spriden_last_name||', '||al3.spriden_first_name,
       (select   sfrstcr_crn,
                 listagg(spriden_last_name || ', ' || spriden_first_name, 'and ')
                   within group (order by spriden_last_name desc)
        from     request req
        where    sfrstcr_crn = al1.sfrstcr_crn
        group by sfrstcr_crn) "All Instructors"
    from   saturn.sfrstcr al1
       left outer join saturn.sirasgn al2 on (al1.sfrstcr_term_code = al2.sirasgn_term_code
                                              and al1.sfrstcr_crn = al2.sirasgn_crn)
       left outer join saturn.spriden al3 on (al2.sirasgn_pidm = al3.spriden_pidm(+))
    where  al3.spriden_change_ind is null
    and    al1.sfrstcr_term_code = '201660';
    

    不幸的是,这会返回错误:

      

    ORA-00933:SQL命令未正确结束

    我认为,根据一些搜索,它可能在某种程度上是引号没有正确导入,所以我尝试了更基本的东西:

    select distinct
       al1.sfrstcr_term_code,
       al1.sfrstcr_crn,
       al3.spriden_first_name,
       al3.spriden_last_name
    from   saturn.sfrstcr al1
       left outer join saturn.sirasgn al2 on (al1.sfrstcr_term_code = al2.sirasgn_term_code
                                              and al1.sfrstcr_crn = al2.sirasgn_crn)
       left outer join saturn.spriden al3 on (al2.sirasgn_pidm = al3.spriden_pidm(+))
    where  al3.spriden_change_ind is null;
    

    但我仍然得到同样的错误......我试着寻找其他可能导致它的东西,但没有找到任何有用的东西......我不知道还有什么可以尝试。

3 个答案:

答案 0 :(得分:1)

试试这个。

select class_id,
LISTAGG((Instructor_Last_Name||', '||Instructor_First_Name), 'and '))
WITHIN GROUP (ORDER BY Instructor_Last_Name DESC) "All Instructors"
FROM Request
group by class_id

答案 1 :(得分:0)

答案 2 :(得分:0)

我认为你正在追求以下方面:

with sample_data as (select 'Bob' first_name, 'Jones' last_name, 1 course_id from dual union all
                     select 'John' first_name, 'Bloggs' last_name, 1 course_id from dual union all
                     select 'Fred' first_name, 'Hoskins' last_name, 1 course_id from dual union all
                     select 'Bob' first_name, 'Jones' last_name, 2 course_id from dual union all
                     select 'John' first_name, 'Bloggs' last_name, 2 course_id from dual union all
                     select 'Fred' first_name, 'Hoskins' last_name, 3 course_id from dual)
-- end of setting up a subquery to mimic a table called sample_data for use in the SQL below:
select course_id,
       listagg(first_name||' '||last_name, ', ') within group (order by last_name) instructors
from   sample_data
group by course_id;


 COURSE_ID INSTRUCTORS                             
---------- ----------------------------------------
         1 John Bloggs, Fred Hoskins, Bob Jones    
         2 John Bloggs, Bob Jones                  
         3 Fred Hoskins         

请注意我已将CONCAT替换为||,因为它更加灵活,如果您加入的是CONCAT,则不需要select distinct al1.sfrstcr_term_code, al1.sfrstcr_crn, al3.spriden_first_name, al3.spriden_last_name, al3.spriden_last_name||', '||al3.spriden_first_name, (select student_registration_crn, listagg(instructor_last_name || ', ' || instructor_first_name, 'and ') within group (order by instructor_last_name desc) from request req where <join condition(s) between this query and the main query> group by student_registration_crn) "All Instructors" from saturn.sfrstcr al1 left outer join saturn.sirasgn al2 on (al1.sfrstcr_term_code = al2.sirasgn_term_code and al1.sfrstcr_crn = al2.sirasgn_crn) left outer join saturn.spriden al3 on (al2.sirasgn_pidm = al3.spriden_pidm(+)) where al3.spriden_change_ind is null and al1.sfrstcr_term_code = '201660'; 的嵌套串起来!它也更容易阅读。

我怀疑你正在寻找的查询是这样的:

php

您的查询存在一些我已更正的问题:

  1. 标量子查询(使用select语句填充列时)需要括在括号中。
  2. 尽可能使用较新的ANSI样式连接,而不是旧式连接。
  3. 您缺少从标量子查询到外部查询的连接条件 - 您需要包含这些条件。此外,标量子查询最多需要返回一行,否则您将收到错误。