1

I have a table like that:

 +----+-----+------+
 | id | ord | test |
 +----+-----+------+
 |  1 |   1 | A    |
 |  1 |   2 | B    |
 |  1 |   3 | C    |
 |  2 |   1 | B    |
 |  2 |   2 | C    |
 +----+-----+------+

(Here is some code for creating the data)

drop table temp_test;
create table temp_test (id varchar(20), ord varchar(20), test varchar(20));
insert into temp_test (id,ord,test) values ('1','1','A');
insert into temp_test (id,ord,test) values ('1','2','B');
insert into temp_test (id,ord,test) values ('1','3','C');
insert into temp_test (id,ord,test) values ('2','1','B');
insert into temp_test (id,ord,test) values ('2','2','C');
commit;

How could I get the following result?

+----+-----+-------+
| id | ord | test  |
+----+-----+-------+
|  1 |   1 | A     |
|  1 |   2 | A_B   |
|  1 |   3 | A_B_C |
|  2 |   1 | B     |
|  2 |   2 | B_C   |
+----+-----+-------+

I have tried using LAG(), something like:

  select CONCAT(lag(TEST) over (partition by ID order by ord),TEST) AS TEST from temp_test;

but it does not work recursively.

This code works:

SELECT 
R1.*,
(   SELECT  LISTAGG(test, ';') WITHIN GROUP (ORDER BY ord)
    FROM    temp_test R2
    WHERE   R1.ord >= R2.ord
    AND     R1.ID = R2.ID
    GROUP BY ID
) AS WTR_KEYWORD_1
FROM temp_test R1
ORDER BY id, ord;

but it is not performant enough for a larger data set.

2 Answers 2

1

Some say the Hierarchical queries are outdated, but they generally perform far better than recursive CTE

SELECT id,
       ord,
       LTRIM(sys_connect_by_path(test,'_'),'_') as test
FROM temp_test r2 START WITH ord = 1 -- use MIN() to get this if it's not always 1
CONNECT BY PRIOR id = id AND ord = PRIOR ord + 1;

Demo

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that is the fastest answer.
1

you can make use of recursive cte to achieve this

with cte(id,ord,test,concat_val) 
  as (select id,ord,test,test as concat_val
       from temp_test
       where ord=1
      union all
      select a.id,a.ord,a.test,b.concat_val||'_'||a.test
        from temp_test a
        join cte b
          on a.id=b.id
         and a.ord=b.ord+1 
      )
select * from cte order by id,ord

Demo here

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=78baa20f7f364e653899caf63ce7ada2

2 Comments

That provides the correct result. I will check the performance. Thanks a lot!
The result is correct, but the accepted answer is about 100x faster on my data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.