listagg数据为可用格式?

Cli*_*iff 6 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;
Run Code Online (Sandbox Code Playgroud)

产量:

LISTAGG结果

Ale*_*ole 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 
Run Code Online (Sandbox Code Playgroud)

...我无法从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
Run Code Online (Sandbox Code Playgroud)

正如文档所说,listagg()函数总是返回varchar2(或raw),因此传入一个nvarchar2值会导致隐式转换,从而导致结果丢失.

如果您坚持使用该数据类型的列,则可以将其转换varchar2listagg调用内部:

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               
Run Code Online (Sandbox Code Playgroud)

但你可能根本不想要它nvarchar2.


Tao*_*que 7

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

...listagg(convert(firstname, 'UTF8', 'AL16UTF16'), ', ')...
Run Code Online (Sandbox Code Playgroud)

  • @Cliff - 只是指出警告.如果这两个字符集是您的数据库和国家字符集,那么它将起作用,但我会首先考虑为什么你有错误的字符集. (3认同)