繁体   English   中英

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

[英]Oracle 8i SQL - concatenate strings from different rows

我需要串联来自不同行的字符串,如下所示。
每个NAME的行数是可变的,并且其范围是未知的。

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
  • 没有WM_CONCAT
  • 没有参考光标
  • 否SYS_CONNECT_BY_PATH

我是SOL吗?

Oracle 8i至少支持分析功能,因此您可以使用row_number()dense_rank()每个颜色值分配一个标称数字(按您认为有意义的顺序):

select name, color,
  row_number() over (partition by name order by color) as rn
from your_table;

然后在手动数据透视表上使用一个变体,每个可能的行号使用一个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中进行测试,因为我找不到一个可以旋转的旧实例,但是我不认为这会在以后使用任何引入的东西...)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM