【问题标题】:Ordering the strings while concatenating in oracle在 oracle 中连接时对字符串进行排序
【发布时间】:2013-01-23 10:19:44
【问题描述】:

我正在使用 collect 函数来连接 sql 查询的字符串。

    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

下面是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。

谢谢 废话

【问题讨论】:

    标签: oracle oracle10g


    【解决方案1】:

    要获得有序列表,有几种方法。最简单的是:

    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
    

    【讨论】:

    • 另一种选择是使用collect(... order by de.eventDate)。该语法记录在 11g 中,而不是 10g,但在 10g 中仍然有效。
    猜你喜欢
    • 2020-11-21
    • 2020-09-16
    • 1970-01-01
    • 2013-11-21
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多