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