我正在尝试使用string_agg函数detailed here来处理distinct关键字。样品用法:
select string_agg(distinct a.name), a.id from tbl_a a group by a.id
问题是这在sqldeveloper中有效,但是当它在一个匿名的pl / sql块中的application express中运行时,它拒绝接受distinct关键字,并且我得到一个错误,说明不允许使用distinct。为什么要这样做?有一个简单的解决方法吗?我使用10.2和application express 3.2
编辑:澄清一下,我有兴趣解决这个问题,但如果还有另一个我可以使用的string_agg / group_concat函数,我会对任何想法持开放态度。
编辑:我最终希望能够做类似
的事情select string_agg(distinct a.name),string_agg(distinct a.city), a.id from tbl_a a group by a.id
并且重复使用两个string_agg列...这在子查询中使用distinct时会出现问题,因为它没有获得两列的不同值...
答案 0 :(得分:1)
根据此AskTom thread中的最后一篇文章,此行为似乎是一个错误。
将不同操作移动到子查询中应该有效:
select string_agg(sq.name)
,sq.id
from (
select distinct
a.name
,a.id
from tbl_a a
) sq
group by sq.id
答案 1 :(得分:1)
-- Subject: string_agg + distinct/unique
-- Function string_agg creates a comma separated list of cursor values
-- Source : http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php
-- This function has been renamed to string_agg_unique and modified to return a unique list of values (unsort)
-- (The merge part has not been modified/supported)
CREATE OR REPLACE TYPE t_string_agg_unique AS OBJECT
(
g_string VARCHAR2(32767),
STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT t_string_agg_unique)
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_string_agg_unique,
value IN VARCHAR2 )
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate(self IN t_string_agg_unique,
returnValue OUT VARCHAR2,
flags IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_string_agg_unique,
ctx2 IN t_string_agg_unique)
RETURN NUMBER
);
/
SHOW ERRORS
CREATE OR REPLACE TYPE BODY t_string_agg_unique IS
STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT t_string_agg_unique)
RETURN NUMBER IS
BEGIN
sctx := t_string_agg_unique(NULL);
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_string_agg_unique,
value IN VARCHAR2 )
RETURN NUMBER IS
BEGIN
-- Concatenate string only when not already existing in the list (=unique)
IF instr ( SELF.g_string||',' , ','||value||',' ) = 0
THEN
SELF.g_string := self.g_string || ',' || value;
END IF ;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateTerminate(self IN t_string_agg_unique,
returnValue OUT VARCHAR2,
flags IN NUMBER)
RETURN NUMBER IS
BEGIN
returnValue := RTRIM(LTRIM(SELF.g_string, ','), ',');
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_string_agg_unique,
ctx2 IN t_string_agg_unique)
RETURN NUMBER IS
BEGIN
SELF.g_string := SELF.g_string || ',' || ctx2.g_string;
RETURN ODCIConst.Success;
END;
END;
/
SHOW ERRORS
CREATE OR REPLACE FUNCTION string_agg_unique (p_input VARCHAR2)
RETURN VARCHAR2
PARALLEL_ENABLE AGGREGATE USING t_string_agg_unique;
/
SHOW ERRORS
-- example
select string_agg_unique ( fruit ) fruit_list from (
select * from (
select 'Apple' fruit from dual
union all
select 'Cherries' fruit from dual
union all
select 'Apple' fruit from dual
union all
select 'Lemon' fruit from dual
)
) ;
苹果,樱桃,柠檬