listagg 数据转换为可用格式?
Posted
技术标签:
【中文标题】listagg 数据转换为可用格式?【英文标题】:listagg data to useable format? 【发布时间】:2015-05-02 23:04:37 【问题描述】:这是我第一次使用 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;
产量:
【问题讨论】:
你能告诉我们“格式奇怪”是什么意思吗?您没有得到的预期输出是什么? @ruudvan 为清楚起见进行了编辑。USERS
列的字符之间都有空格,当尝试复制粘贴时,不会复制该列中的数据。
子查询返回用户名不带空格?
无法复制可能是由于 IDE 中的某些问题。您使用的是哪个 IDE? (如 Toad 或 plsql 开发人员)?此外,查询中似乎没有任何添加空格的内容。独立运行子查询以确保表中的数据中没有这些空格。
@ruudvan 我已经尝试过 dbForge Studio Express 和 Oracle SQL Developer。两者的行为相同。
【参考方案1】:
显然这是 11 中的一个已知(未解决?)错误。TO_CHAR() 为我工作...
SELECT wiporderno, LISTAGG(TO_CHAR(medium), ',') WITHIN GROUP(ORDER BY wiporderno) AS jobclassification
...medium 是有问题的列/数据类型。
【讨论】:
IMO 值得添加 bug# 和简短描述:Bug 19461687 LISTAGG return value contains ASCII 0x00 bytes for NVARCHAR with no delimiter specified (MOS Doc ID: 19461687.8)
【参考方案2】:
您的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
值会导致隐式转换,从而丢弃您的结果。
如果您的列属于该数据类型,您可以在 listagg
调用中将其转换为 varchar2
:
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
。
【讨论】:
【参考方案3】:我有类似的问题,原来是编码的问题。我像这样解决了这个问题(如果需要,更改为另一种编码):
...listagg(convert(firstname, 'UTF8', 'AL16UTF16'), ', ')...
【讨论】:
Oracle discourages the use ofconvert
虽然,如文档中所述;即使这是为了更正存储在错误字符集中的数据。如果varchar2
和nvarchar2
存储之间存在差异,那么强制转换似乎更合适。如果您有更广泛的字符集问题,那么这可能不安全。取决于,就像很多事情一样......
@AlexPoole 为什么会这样?这篇文章似乎表明这是应该使用它的时间。
@Cliff - 只是指出警告。如果这两个字符集是您的数据库和国家字符集,那么它会起作用,但我会先看看为什么您的字符集错误。以上是关于listagg 数据转换为可用格式?的主要内容,如果未能解决你的问题,请参考以下文章
MAPGIS的WL\WP\WT数据可否成批转换成ARCGIS数据格式?转换后是不是可用