2014-03-01 48 views
0

所有,所有的值甲骨文聚合函数以及如何连接在列

我的Oracle数据库版本为10g企业版发布10.2.0.5.0 - 64位

我有以下声明,有效地得到我的最大(或最小或计数等)值在每种情况下如预期但我想要得到并连接所有的值,而不是最大值,最小值或计数 - 是否有一个优雅的方式来做到这一点?

SELECT lla.id, 
     max(decode(lla.attrid, 2, lla.valstr, null)) "Attribute Name 2", 
     min(decode(lla.attrid, 3, lla.valstr, null)) "Attribute Name 3", 
     count(decode(lla2.attrid, 5, lla2.valstr, null)) "Attribute Name 5" 
FROM llattrdata lla, llattrdata lla2 
WHERE lla.id = lla2.id 
     AND lla.defid = 111111 --category id 1 
     AND lla2.defid = 222222 --category id 2 
     AND lla.id = 48212327 and lla2.id = 48212327 
     GROUP BY lla.id 

希望有一个排,看起来是这样的:

12121212 | fred, jack, gill | 56 | 29,10 

更清晰那就是“属性名3”(例如)包含了我希望看到所有的值而不仅仅是最大值或最小值。换句话说,对于这个属性,我可以获得最大值或最小值,甚至可以计数但是看不到获取所有值的方法?换句话说,我可以得到10分作为最小值,29作为最大值 - 即使是2,但在同一列中不能得到29和10!

提前许多感谢,

+2

为什么所有这些反引号? – Alexander

+0

使用'||'拼接。例如'选择'conca'|| 'tenation'FROM DUAL;' – Alexander

回答

2
SELECT e.department_id, 
     listagg(e.first_name) within group (order by e.department_id) "Attribute Name 2" 
FROM employees e join 
    departments d 
    on e.department_id = d.department_id 
GROUP BY e.department_id; 

你可以使用上面的例子,并改变你的查询

+1

谢谢你的回答,但除非我误解了Oracle 11g第2版中引入了LISTAGG分析功能。 – user3367673

+0

似乎** LISTAGG **在Oracle 10中未记录。 – gavenkoa

0

使用wmsys.wm_concat功能learn more here它。这是Oracle 10中未记录的功能。

它返回你用逗号分隔的列表,你可以用replace函数来替换你所需要的东西。

不幸的是,此功能没有order子句,因此您无法在列表中指定顺序。

编辑:

至于此功能不适用于你,你可以简单地创建它:

CREATE OR REPLACE TYPE wm_concat_impl 
    AUTHID CURRENT_USER 
AS OBJECT (
    curr_str VARCHAR2 (32767), 
    STATIC FUNCTION odciaggregateinitialize (sctx IN OUT wm_concat_impl) 
     RETURN NUMBER, 
    MEMBER FUNCTION odciaggregateiterate (
     SELF IN OUT wm_concat_impl, 
     p1  IN  VARCHAR2 
    ) 
     RETURN NUMBER, 
    MEMBER FUNCTION odciaggregateterminate (
     SELF   IN  wm_concat_impl, 
     returnvalue OUT  VARCHAR2, 
     flags   IN  NUMBER 
    ) 
     RETURN NUMBER, 
    MEMBER FUNCTION odciaggregatemerge (
     SELF IN OUT wm_concat_impl, 
     sctx2 IN  wm_concat_impl 
    ) 
     RETURN NUMBER 
); 
/

CREATE OR REPLACE TYPE BODY wm_concat_impl 
IS 
    STATIC FUNCTION odciaggregateinitialize (sctx IN OUT wm_concat_impl) 
     RETURN NUMBER 
    IS 
    BEGIN 
     sctx := wm_concat_impl (NULL); 
     RETURN odciconst.success; 
    END; 
    MEMBER FUNCTION odciaggregateiterate (
     SELF IN OUT wm_concat_impl, 
     p1  IN  VARCHAR2 
    ) 
     RETURN NUMBER 
    IS 
    BEGIN 
     IF (curr_str IS NOT NULL) 
     THEN 
     curr_str := curr_str || ',' || p1; 
     ELSE 
     curr_str := p1; 
     END IF; 

     RETURN odciconst.success; 
    END; 
    MEMBER FUNCTION odciaggregateterminate (
     SELF   IN  wm_concat_impl, 
     returnvalue OUT  VARCHAR2, 
     flags   IN  NUMBER 
    ) 
     RETURN NUMBER 
    IS 
    BEGIN 
     returnvalue := curr_str; 
     RETURN odciconst.success; 
    END; 
    MEMBER FUNCTION odciaggregatemerge (
     SELF IN OUT wm_concat_impl, 
     sctx2 IN  wm_concat_impl 
    ) 
     RETURN NUMBER 
    IS 
    BEGIN 
     IF (sctx2.curr_str IS NOT NULL) 
     THEN 
     SELF.curr_str := SELF.curr_str || ',' || sctx2.curr_str; 
     END IF; 

     RETURN odciconst.success; 
    END; 
END; 
/

CREATE OR REPLACE FUNCTION wm_concat (p1 VARCHAR2) 
    RETURN VARCHAR2 
    AGGREGATE USING wm_concat_impl; 
/

查询从this website拍摄,这是不幸的是,在俄罗斯,但只是为了你的目的使用这个自定义聚合函数。

+0

Simon - 这当然是在正确的轨道上(尽管我的糟糕解释 - 现在更新了一些!),但似乎这个未公开的功能不可用 - 有没有办法让我失去它? – user3367673

+0

已更新,您可以自己创建此功能。 – smnbbrv

+0

Simon - 我非常欣赏坚韧不拔,现在已经具备了自定义聚合功能。当然,现在我经常遇到这样的情况:在添加调用''后,我得到一个'ORA-00937:不是一个单独的组函数',max(decode(lla.attrid,20,wm_concat(lla.valstr),null ))“concat_attrs”'... – user3367673

0

试试这个:

SELECT lla.id || ' | ' || 
     max(decode(lla.attrid, 2, lla.valstr, null)) || ' | ' || 
     min(decode(lla.attrid, 3, lla.valstr, null)) || ' | ' || 
     count(decode(lla2.attrid, 5, lla2.valstr, null)) 
FROM llattrdata lla, llattrdata lla2 
WHERE lla.id = lla2.id 
     AND lla.defid = 111111 --category id 1 
     AND lla2.defid = 222222 --category id 2 
     AND lla.id = 48212327 and lla2.id = 48212327 
     GROUP BY lla.id 
+0

谢谢你的回答 - 我已经增加了一些更多的问题,因为我怀疑在重新阅读我的文章中并不清楚。 – user3367673

0

我有同样的问题和所使用的STRAGG(如串集合)由汤姆·凯特创建功能。

https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:15637744429336

create or replace type stragg_type as object 
(
    string varchar2(4000), 
    static function ODCIAggregateInitialize 
    (sctx in out stragg_type) 
    return number , 
    member function ODCIAggregateIterate 
    (self in out stragg_type , 
     value in  varchar2 
    ) return number , 
    member function ODCIAggregateTerminate 
    (self  in stragg_type, 
     returnvalue out varchar2, 
     flags in number 
    ) return number , 
    member function ODCIAggregateMerge 
    (self in out stragg_type, 
     ctx2 in  stragg_type 
    ) return number 
); 
/

create or replace type body stragg_type 
is 
    static function ODCIAggregateInitialize 
    (sctx in out stragg_type) 
    return number 
    is 
    begin 
    sctx := stragg_type(null) ; 
    return ODCIConst.Success ; 
    end; 
    member function ODCIAggregateIterate 
    (self in out stragg_type , 
    value in  varchar2 
) return number 
    is 
    begin 
    self.string := self.string || ',' || value ; 
    return ODCIConst.Success; 
    end; 
    member function ODCIAggregateTerminate 
    (self  in stragg_type , 
    returnvalue out varchar2 , 
    flags  in number 
) return number 
    is 
    begin 
    returnValue := ltrim(self.string, ','); 
    return ODCIConst.Success; 
    end; 
    member function ODCIAggregateMerge 
    (self in out stragg_type , 
    ctx2 in  stragg_type 
) return number 
    is 
    begin 
    self.string := self.string || ctx2.string; 
    return ODCIConst.Success; 
    end; 
end; 
/

create or replace function stragg 
    (input varchar2) 
    return varchar2 
    deterministic 
    parallel_enable 
    aggregate using stragg_type 
; 
/

运行三个语句创建一个接一个地在sqlplus或sqldev之后。现在,stragg()函数在您的用户架构中创建。那么你可以这样做:

SELECT lla.id, 
     max(decode(lla.attrid, 2, lla.valstr, null)) "Attribute Name 2", 
     STRAGG(decode(lla.attrid, 3, lla.valstr, null)) "Attribute Name 3 List", 
     count(decode(lla2.attrid, 5, lla2.valstr, null)) "Attribute Name 5" 
FROM llattrdata lla, llattrdata lla2 
WHERE lla.id = lla2.id 
     AND lla.defid = 111111 --category id 1 
     AND lla2.defid = 222222 --category id 2 
     AND lla.id = 48212327 and lla2.id = 48212327 
GROUP BY lla.id