Oracle 8i SQL-连接来自不同行的字符串

Oracle 8i SQL-连接来自不同行的字符串,sql,string,oracle,concatenation,oracle8i,Sql,String,Oracle,Concatenation,Oracle8i,我需要连接来自不同行的字符串,如下所示。 每个名称的行数是可变的,其范围未知 NAME COLOR Bob Red Bob Blue Tom Green John Red John Yellow John Purple 期望输出: NAME COLORS Bob RedBlue Tom Green John RedYellowPurple 我面临的限制是: Oracle 8i(8.1.7.4.0)-我无法控制这一点,升级是不可能的 别无选择 只读访问 无法创

我需要连接来自不同行的字符串,如下所示。
每个名称的行数是可变的,其范围未知

NAME  COLOR
Bob   Red
Bob   Blue
Tom   Green
John  Red
John  Yellow
John  Purple
期望输出:

NAME  COLORS
Bob   RedBlue
Tom   Green
John  RedYellowPurple
我面临的限制是:

  • Oracle 8i(8.1.7.4.0)-我无法控制这一点,升级是不可能的 别无选择
  • 只读访问
  • 无法创建
所以基本上:

  • 不创造
  • 没有LISTAGG
  • 没有XMLAGG
  • 不知道
  • 无参考光标
  • 没有系统连接路径

我是SOL吗?

Oracle 8i至少支持分析功能,因此您可以使用或
稠密等级()为每个颜色值指定一个标称值(按您认为合理的顺序排列):

然后在手动轴上使用一个变体,每个可能的行号有一个
max(decode())

select name,
  max(decode(rn, 1, color))
  || max(decode(rn, 2, color))
  || max(decode(rn, 3, color))
  || max(decode(rn, 4, color))
  || max(decode(rn, 5, color))
  || max(decode(rn, 6, color))
  || max(decode(rn, 7, color))
  -- ...
  as colors
from (
  select name, color,
    row_number() over (partition by name order by color) as rn
  from your_table
)
group by name
order by name;

NAME       COLORS                                                                
---------- ----------------------------------------------------------------------
Bob        BlueRed                                                               
John       PurpleRedYellow                                                       
Tom        Green                                                                 
您说范围未知,但即使每个名称的行数不受限制,您仍然受到最终连接字符串的限制,该字符串最多必须为4000个字符-根据您对实际颜色值的了解,实际颜色值将为您提供最大可用数。(您可以一次性自动生成解码部分)

如果需要,可以使用相同的方式包括分隔符:

select name,
  max(decode(rn, 1, color))
  || max(decode(rn, 2, ',')) || max(decode(rn, 2, color))
  || max(decode(rn, 3, ',')) || max(decode(rn, 3, color))
  || max(decode(rn, 4, ',')) || max(decode(rn, 4, color))
  || max(decode(rn, 5, ',')) || max(decode(rn, 5, color))
  || max(decode(rn, 6, ',')) || max(decode(rn, 6, color))
  || max(decode(rn, 7, ',')) || max(decode(rn, 7, color))
  || max(decode(rn, 8, ',')) || max(decode(rn, 8, color))
  -- ...
  as colors
from (
  select name, color,
    row_number() over (partition by name order by color) as rn
  from your_table
  where color is not null
)
group by name
order by name;

NAME       COLORS                                                                                 
---------- ---------------------------------------------------------------------------------------
Bob        Blue,Red                                                                               
John       Purple,Red,Yellow                                                                      
Tom        Green                                                                                  
我在内部查询中包含了一个
is not null
过滤器,以防该列可为空—这应该可以防止最终列表中出现空元素


(未在8i中测试,因为我找不到一个如此古老的实例,但我不认为这是在使用后面介绍的任何东西…

这将是一个困难的问题,可能通过级别和总和连接?一个用于计算每个名称的颜色数的子查询,以及一个连接方式查询,该查询使用level语句连接,直到达到计数为止。现在如何运行Oracle 8i?您能创建函数吗?@WernfriedDomscheit,我不能创建函数。这是一个遗留系统,我从中提取数据。我完全无法控制任何事情。仅供参考,它与Tcl/Tk前端一起运行,不再进行维护,尽管它已投入关键的日常运营。此外,该公司只剩下一名8i数据库管理员,他已经忙着阻止8i数据库出现腐败。但是,我们在这里偏离了重点:-)我将在周一的工作中测试这个。我刚刚检查了row_number()确实是Oracle SQL引用的8i分析函数的一部分,所以它应该可以工作。好的,如果我们假设“颜色”是由一组相对较小的唯一值组成的,那么这就可以了。然而,理论上,“rn”的值确实可以是无限的。因此,这可能是一种工作,但不是在所有情况下。我知道“rn”越大,就越接近4000的极限。然而,有人不能在连接发生之前将varchar2转换为LONG或CLOB以避免达到这个限制吗?
select name,
  max(decode(rn, 1, color))
  || max(decode(rn, 2, ',')) || max(decode(rn, 2, color))
  || max(decode(rn, 3, ',')) || max(decode(rn, 3, color))
  || max(decode(rn, 4, ',')) || max(decode(rn, 4, color))
  || max(decode(rn, 5, ',')) || max(decode(rn, 5, color))
  || max(decode(rn, 6, ',')) || max(decode(rn, 6, color))
  || max(decode(rn, 7, ',')) || max(decode(rn, 7, color))
  || max(decode(rn, 8, ',')) || max(decode(rn, 8, color))
  -- ...
  as colors
from (
  select name, color,
    row_number() over (partition by name order by color) as rn
  from your_table
  where color is not null
)
group by name
order by name;

NAME       COLORS                                                                                 
---------- ---------------------------------------------------------------------------------------
Bob        Blue,Red                                                                               
John       Purple,Red,Yellow                                                                      
Tom        Green