listagg数据为可用格式?

时间:2015-03-02 14:39:25

标签: database oracle concatenation listagg

这是我第一次使用LISTAGG功能,我很困惑。我可以很容易地选择数据,但USERS列的字符在它们之间都有空格,并且在尝试复制它时,不会复制该列中的数据。我尝试过两种不同的IDE。我做错了吗?

示例:

select course_id, listagg(firstname, ', ') within group (order by course_id) as users
    from (
      select distinct u.firstname, u.lastname, u.student_id, cm.course_id
      from course_users cu
      join users u on u.pk1 = cu.users_pk1
      join course_main cm on cm.pk1 = cu.crsmain_pk1
      and cm.course_id like '2015SP%'
      )
group by course_id;

收率:

LISTAGG result

3 个答案:

答案 0 :(得分:8)

您的firstname列似乎定义为nvarchar2

with t as (
  select '2015SP.BOS.PPB.556.A'as course_id,
    cast('Alissa' as nvarchar2(10)) as firstname
  from dual
  union all select '2015SP.BOS.PPB.556.A'as course_id,
    cast('Dorothea' as nvarchar2(10)) as firstname
  from dual
)
select course_id, listagg(firstname, ', ')
  within group (order by course_id) as users
from t
group by course_id;

COURSE_ID            USERS                         
-------------------- ------------------------------
2015SP.BOS.PPB.556.A 

...我无法从SQL Developer复制/粘贴用户值,但它会显示空格,正如您从SQL * Plus中看到的那样:

COURSE_ID            USERS
-------------------- ------------------------------
2015SP.BOS.PPB.556.A  A l i s s a,  D o r o t h e a

正如文档所说,listagg()函数始终返回varchar2(或raw),因此传入nvarchar2值会导致隐式转换,这会导致您丢失结果

如果您的列属于该数据类型,则可以将其转换为varchar2来电中的listagg

column users format a30
with t as (
  select '2015SP.BOS.PPB.556.A'as course_id,
    cast('Alissa' as nvarchar2(10)) as firstname
  from dual
  union all select '2015SP.BOS.PPB.556.A'as course_id,
    cast('Dorothea' as nvarchar2(10)) as firstname
  from dual
)
select course_id, listagg(cast(firstname as varchar2(10)), ', ')
  within group (order by course_id) as users
from t
group by course_id;

COURSE_ID            USERS                         
-------------------- ------------------------------
2015SP.BOS.PPB.556.A Alissa, Dorothea               

但你可能根本不想让它成为nvarchar2

答案 1 :(得分:7)

我有类似的问题,原来问题是编码问题。我得到了这样解决(如果需要,改为另一种编码):

...listagg(convert(firstname, 'UTF8', 'AL16UTF16'), ', ')...

答案 2 :(得分:3)

显然,这是一个已知(未解决?)的错误11. TO_CHAR()为我工作......

SELECT wiporderno, LISTAGG(TO_CHAR(medium), ',') WITHIN GROUP(ORDER BY wiporderno) AS jobclassification 

...介质是有问题的列/数据类型。