简体   繁体   English

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

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

I need to concatenate strings from different rows, as below. 我需要串联来自不同行的字符串,如下所示。
The number of rows for each NAME is variable and its range is unknown. 每个NAME的行数是可变的,并且其范围是未知的。

NAME  COLOR
Bob   Red
Bob   Blue
Tom   Green
John  Red
John  Yellow
John  Purple

Desired output: 所需的输出:

NAME  COLORS
Bob   RedBlue
Tom   Green
John  RedYellowPurple

The limitations I am facing are : 我面临的局限性是:

  • Oracle 8i (8.1.7.4.0) - I have no control over this and upgrading is not an option Oracle 8i(8.1.7.4.0)-我对此无能为力,无法升级
  • read only access 只读访问
  • can't create... 无法创建...

So basically : 所以基本上:

  • no CREATE 没有创建
  • no LISTAGG 没有LISTAGG
  • no XMLAGG 没有XMLAGG
  • no WM_CONCAT 没有WM_CONCAT
  • no Ref Cursor 没有参考光标
  • no SYS_CONNECT_BY_PATH 否SYS_CONNECT_BY_PATH

Am I SOL ? 我是SOL吗?

Oracle 8i at least supports analytic functions, so you could assign each color value a nominal number with row_number() or dense_rank() (ordering by whatever makes sense to you): Oracle 8i至少支持分析功能,因此您可以使用row_number()dense_rank()每个颜色值分配一个标称数字(按您认为有意义的顺序):

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

and then use a variation on a manual pivot with one max(decode()) per possible row number: 然后在手动数据透视表上使用一个变体,每个可能的行号使用一个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                                                                 

You said the range is unknown, but even if there are an unlimited number of rows for each name, you're still restricted by the final concatenated string having to be at most 4000 characters - from your knowledge of the actual color values that would give you a maximum usable number. 您说的范围是未知的,但是即使每个名称的行数不受限制,但最终的字符串仍必须限制为最多4000个字符-根据您对实际颜色值的了解,您可以使用的最大数量。 (And you could generate the decode parts automatically as a one-off thing). (并且您可以一次性生成解码部分)。

You could include delimiters the same way if you needed to: 如果需要,可以用相同的方式包括定界符:

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                                                                                  

I've included a is not null filter in the inner query just in case that column is nullable - that ought to prevent empty elements in the final list. 我在内部查询中包含了一个is not null过滤器,以防万一该列可为空-应该防止最终列表中的空元素。

(Not tested in 8i as I can't find an instance that old to spin up, but I don't think this is using anything introduced later...) (未在8i中进行测试,因为我找不到一个可以旋转的旧实例,但是我不认为这会在以后使用任何引入的东西...)

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

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