ORACLE 10g 中的三列字符串聚合

Posted

技术标签:

【中文标题】ORACLE 10g 中的三列字符串聚合【英文标题】:String Aggregation in ORACLE 10g with three columns 【发布时间】:2015-10-29 14:46:11 【问题描述】:

这是一个示例表数据

  Date | Fruit | Number
 -----------------------
   1   | Apple |   1
   1   | Apple |   2
   1   | Apple |   3
   1   |  Kiwi |   6
   1   |  Kiwi |  10
   2   | Apple |   4
   2   | Apple |   5
   2   | Apple |   6
   2   |  Kiwi |   4
   2   |  Kiwi |   7

我尝试连接表格列值以获得以下内容:

  Date | Fruit | Number
 -----------------------
   1   | Apple |  1-2-3
   1   |  Kiwi |   6-10
   2   | Apple |  4-5-6
   2   |  Kiwi |    4-7

我使用的代码:

SELECT fruit,
       LTRIM( MAX(SYS_CONNECT_BY_PATH(number,','))
               KEEP (DENSE_RANK LAST ORDER BY curr), ',') AS fruits_agg
  FROM( SELECT Date,
               fruit,
               number,
               ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY number) AS curr,
               ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY number) - 1 AS prev
          FROM table_name)

  GROUP BY Date,fruit
  CONNECT BY prev = PRIOR curr AND fruit = PRIOR fruit AND Date = PRIOR Date
  START WITH curr = 1;

它没有按照我想要的方式工作。我哪里做错了?

PS:我的版本是10g,所以我不能使用listagg

【问题讨论】:

【参考方案1】:

对于 Oracle 10,使用您的方法 - 问题在于您的内部查询中的分区。

WITH tab as (
SELECT 1 as fdate,     'Apple' as fruit,    1 as num from dual union
SELECT 1 as fdate,     'Apple' as fruit,    2 as num from dual union
SELECT 1 as fdate,     'Apple' as fruit,    3 as num from dual union
SELECT 1 as fdate,     'Kiwi' as fruit,    6 as num from dual union
SELECT 1 as fdate,     'Kiwi' as fruit,    10 as num from dual union
SELECT 2 as fdate,     'Apple' as fruit,    4 as num from dual union
SELECT 2 as fdate,     'Apple' as fruit,    5 as num from dual union
SELECT 2 as fdate,     'Apple' as fruit,    6 as num from dual union
SELECT 2 as fdate,     'Kiwi' as fruit,    4 as num from dual union
SELECT 2 as fdate,     'Kiwi' as fruit,    7 as num from dual )
SELECT fdate, fruit,LTRIM(MAX(SYS_CONNECT_BY_PATH(num,','))
    KEEP (DENSE_RANK LAST ORDER BY curr),',') AS fruits_agg
    FROM   (SELECT fdate,
            fruit,
            num,
            ROW_NUMBER() OVER (PARTITION BY fdate, fruit ORDER BY num) AS curr,
            ROW_NUMBER() OVER (PARTITION BY fdate, fruit ORDER BY num) -1 AS prev
     FROM   tab)
  GROUP BY fdate,fruit
  CONNECT BY prev = PRIOR curr AND fruit = PRIOR fruit AND fdate = PRIOR fdate
 START WITH curr = 1;

给予:

FDATE             FRUIT   FRUITS_AGG                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
1                "Kiwi"  "6,10"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
1                "Apple" "1,2,3"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
2                "Kiwi"  "4,7"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
2                "Apple" "4,5,6"

Oracle 11 解决方案要简单得多:

WITH tab as (
SELECT 1 as fdate,     'Apple' as fruit,    1 as num from dual union
SELECT 1 as fdate,     'Apple' as fruit,    2 as num from dual union
SELECT 1 as fdate,     'Apple' as fruit,    3 as num from dual union
SELECT 1 as fdate,     'Kiwi' as fruit,    6 as num from dual union
SELECT 1 as fdate,     'Kiwi' as fruit,    10 as num from dual union
SELECT 2 as fdate,     'Apple' as fruit,    4 as num from dual union
SELECT 2 as fdate,     'Apple' as fruit,    5 as num from dual union
SELECT 2 as fdate,     'Apple' as fruit,    6 as num from dual union
SELECT 2 as fdate,     'Kiwi' as fruit,    4 as num from dual union
SELECT 2 as fdate,     'Kiwi' as fruit,    7 as num from dual )
select fdate
     , fruit
     , listagg(num,'-') within group ( order by num ) fruit_agg
from tab
group by fdate, fruit 

返回:

FDATE  FRUIT    FRUIT_AGG
1      Kiwi      6-10
1      Apple     1-2-3
2      Kiwi      4-7
2      Apple     4-5-6

【讨论】:

listagg 未针对 oracle 10g 发布。我不能用那个。谢谢! 更新答案以解决您的方法中的问题。

以上是关于ORACLE 10g 中的三列字符串聚合的主要内容,如果未能解决你的问题,请参考以下文章

查询以获取 Oracle 10g 中下一行中的 % 符号数 = 字符串长度

Oracle 10g 中的 json

如何在Tableview的三列中放置文本

在 Oracle 10g 上创建聚合函数返回无用的错误

Oracle 10g 从两个不同的行和列聚合成一行

如何在 CLOB 字段(Oracle 10g)中快速替换出现极高的相同字符?