2013-02-07 25 views
1

我正在使用collect函数为sql查询连接字符串。在oracle中连接时排序字符串

select id, 
    tab_to_string(CAST(COLLECT(a.level||' '||d.Number||': 
    '||to_char(nvl(de.eventDate,SYSDATE - 365 * 100))) AS t_varchar2_tab)) AS MyVar 
    from Mytable 
    groupby id 

这个查询的输出是这样的:

Id Myvar 
    1  level : 27-Jan-09,level : 27-Mar-08, level : 2-Apr-10 
    2  level : 7-Jun-06,level : 27-Dec-08, level : 2-Nov-08 
    3  level : 27-July-10,level : 27-Mar-06, level : 2-Apr-10 

但我希望“MYVAR”的数值为在连接字符串中的日期字段排序

所以Id = 1,输出应该像

level : 27-Mar-08, level : 27-Jan-09, level : 2-Apr-10 

Be低是tab_to_string功能

源代码:http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php#wm_concat

CREATE OR REPLACE FUNCTION tab_to_string (p_varchar2_tab IN t_varchar2_tab, 
             p_delimiter  IN VARCHAR2 DEFAULT ',') 
    RETURN VARCHAR2 IS 
    l_string  VARCHAR2(32767); 
    BEGIN 
    FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP 
    IF i != p_varchar2_tab.FIRST THEN 
    l_string := l_string || p_delimiter; 
    END IF; 
    l_string := l_string || p_varchar2_tab(i); 
    END LOOP; 
    RETURN l_string; 
    END tab_to_string; 

我使用Oracle 10g。

感谢 黄芪多糖

回答

2

得到一个有序列表,有几个方法。最简单的是:

select id, str 
    from (select id, 
       wm_concat('level : ' || to_char(nvl(eventDate,SYSDATE - 365 * 100))) 
       over (partition by id order by eventdate) str, 
       row_number() over (partition by id order by eventdate desc) rn 
     from Mytable) 
where rn = 1; 

,或者如果你正在使用的 “stragg” 用户定义的聚合:

select id, str 
    from (select id, 
       string_agg('level : ' || to_char(nvl(eventDate,SYSDATE - 365 * 100))) 
       over (partition by id order by eventdate) str, 
       row_number() over (partition by id order by eventdate desc) rn 
     from Mytable) 
where rn = 1; 

SQL> select id, str 
    2 from (select id, 
    3     string_agg('level : ' || to_char(nvl(eventDate,SYSDATE - 365 * 100))) 
    4     over (partition by id order by eventdate) str, 
    5     row_number() over (partition by id order by eventdate desc) rn 
    6   from Mytable) 
    7 where rn = 1; 

     ID STR 
---------- ---------------------------------------------------------------------- 
     1 level : 27-MAR-08,level : 27-JAN-09,level : 02-APR-10 
     2 level : 07-JUN-06,level : 02-NOV-08,level : 27-DEC-08 
     3 level : 27-MAR-06,level : 02-APR-10,level : 27-JUL-10 
+0

另一种选择是使用'收集(... order by de.eventDate)'。该语法记录在[11g](http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions031.htm#i1271564)中,而不是[10g](http://docs.oracle。 com/cd/B19306_01/server.102/b14200/functions024.htm#i1271564),但仍然适用于10g。 –

+0

@Dazzal它工作得很好。 – Stu