Oracle string_agg(distinct columnname)在pl / sql中不起作用,仅在sqldeveloper中起作用

时间:2009-10-19 00:28:13

标签: sql oracle-apex

我正在尝试使用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时会出现问题,因为它没有获得两列的不同值...

2 个答案:

答案 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  
     )
  ) ; 

FRUIT_LIST

苹果,樱桃,柠檬