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 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 :
So basically :
Am I 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):
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:
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. (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.
(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...)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.