Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Merging two lists and getting a new

sgalaxyFeb 15 2022 — edited Feb 15 2022

Hi,
i have two lists where each member in these should be in the proper order (final list) merging the initial lists.
The rules of ordering are as follows:

  1. if the date_2 of list 1 is less than the date_2 of list 2 then the item of list 1 should get out of its list.
    The item in list 2 (in the above comparison) should remain in the initial list.
  2. if the date_2 of list 1 is greater than the date_2 of list 2 then the item of list 2 should get out of its list.
    The item in list 1 (in the above comparison) should remain in the initial list.
  3. if the date_2 of list 1 is the same as the date_2 of list 2 then :
    a) if the date_1 of list 1 is less than the date_1 of list 2 then the item in list 1 should get out
    of its list and form the final list below of the items they are already in this (final) list.
    b) if the date_1 of list 1 is greater than the date_1 of list 2 then the item in list 2 should get out
    of its list and form the final list below of the items they are already in this (final) list.
  4. It is not possible that both dates in list 1 and list 2 are the same.

A sample of these lists is as follows:

with table_a(code, dates1, dates2) as
(select 'B1', to_date('28/11/2021', 'dd/mm/yyyy'), to_date('30/12/2021', 'dd/mm/yyyy') from dual union all
select 'B2', to_date('13/12/2021', 'dd/mm/yyyy'), to_date('30/1/2022', 'dd/mm/yyyy') from dual union all
select 'B3', to_date('20/12/2021', 'dd/mm/yyyy'), to_date('28/2/2022', 'dd/mm/yyyy') from dual union all
select 'B4', to_date('25/12/2021', 'dd/mm/yyyy'), to_date('30/1/2022', 'dd/mm/yyyy') from dual union all
select 'B5', to_date('2/1/2022', 'dd/mm/yyyy'), to_date('28/2/2022', 'dd/mm/yyyy') from dual union all
select 'B6', to_date('10/1/2022', 'dd/mm/yyyy'), to_date('28/2/2022', 'dd/mm/yyyy') from dual
),
table_b(code, dates1, dates2) as
(select 'AP1', to_date('1/12/2021', 'dd/mm/yyyy'), to_date('15/12/2021', 'dd/mm/yyyy') from dual union all
select 'AP2', to_date('15/12/2021', 'dd/mm/yyyy'), to_date('30/12/2021', 'dd/mm/yyyy') from dual union all
select 'AP3', to_date('25/12/2021', 'dd/mm/yyyy'), to_date('5/1/2022', 'dd/mm/yyyy') from dual union all
select 'AP4', to_date('1/1/2022', 'dd/mm/yyyy'), to_date('15/1/2022', 'dd/mm/yyyy') from dual union all
select 'AP5', to_date('6/1/2022', 'dd/mm/yyyy'), to_date('21/1/2022', 'dd/mm/yyyy') from dual union all
select 'AP6', to_date('28/1/2022', 'dd/mm/yyyy'), to_date('13/2/2022', 'dd/mm/yyyy') from dual

The process of getting the rows in list 1 and list 2 is as follows and referring to the above data:

  1. Get the first record(code: 'B1') of the list 1.
  2. Get the second record(code: 'AP1') of the list 2.
  3. Do the comparison of the two above records regarding their dates2 column values.
  4. The record of code 'AP1' gets out and is put in the first line of the final list.
  5. The record of code 'B1' is compared to the record of code 'AP2'.
  6. Do the comparison and following the rules of ordering described above, the record of code 'B1' gets out of its list and is put second in the final list.
  7. Get the next - which now is first- item in list 1, record of code 'B2'. Also, get the currently
    first item of list 2, record with code 'AP2'.
  8. Do the comparison again between the above (recs, 'B2' and 'AP2'). According to the rules of ordering in the final list, the record with 'AP2' gets out of its list and is put below the items in the final list.
  9. Next, get the record of code 'B2' and also the record of code 'AP3' in list 2.
  10. Do the comparison according to the rules. The record of code 'AP3' is less than of code 'B2', so it gets out of its list and is put below the others in the final list.
  11. Get again the record of code 'B2' and the currently first item in list 2- record of code: 'AP4'.
  12. Doing the comparison according to the rules, the record of code 'AP4' should get out of its list and is put in the final list.
  13. Get again the record of code 'B2' and the currently first item in list 2- record of code: 'AP5'.
  14. Doing the comparison according to the rules, the record of code 'AP5' should get out of its list and is put in the final list below the other items.
  15. Get again the record of code 'B2' and the currently first item in list 2- record of code: 'AP6'.
  16. Do the comparison between the records of code 'B2' and 'AP6'. According to the rules, the record of code 'B2' gets out of its list and is put in the final list.
  17. Get the first record in the current list 1 - rec of code 'B3'. Get also the record of code 'AP6'.
  18. Do the comparison and the record of code 'AP6' (according to the rules) gets out of its list and is put in the final list.
  19. Because there are no other elements in the list 2, all remaining elements in list 1 are put in the final list (in the order of dates1 data column). Of course, if there were other elementsin the list 2, the process would continue as above.

So, to sum up the desired final list should be:
AP1
B1
AP2
AP3
AP4
AP5
B2
AP6
B3
B4
B5
B6

According to the above sample data, i wrote the below sql query to get the desired result set (final list).

with table_a(code, dates1, dates2) as
(select 'B1', to_date('28/11/2021', 'dd/mm/yyyy'), to_date('30/12/2021', 'dd/mm/yyyy') from dual union all
select 'B2', to_date('13/12/2021', 'dd/mm/yyyy'), to_date('30/1/2022', 'dd/mm/yyyy') from dual union all
select 'B3', to_date('20/12/2021', 'dd/mm/yyyy'), to_date('28/2/2022', 'dd/mm/yyyy') from dual union all
select 'B4', to_date('25/12/2021', 'dd/mm/yyyy'), to_date('30/1/2022', 'dd/mm/yyyy') from dual union all
select 'B5', to_date('2/1/2022', 'dd/mm/yyyy'), to_date('28/2/2022', 'dd/mm/yyyy') from dual union all
select 'B6', to_date('10/1/2022', 'dd/mm/yyyy'), to_date('28/2/2022', 'dd/mm/yyyy') from dual
),
table_b(code, dates1, dates2) as
(select 'AP1', to_date('1/12/2021', 'dd/mm/yyyy'), to_date('15/12/2021', 'dd/mm/yyyy') from dual union all
select 'AP2', to_date('15/12/2021', 'dd/mm/yyyy'), to_date('30/12/2021', 'dd/mm/yyyy') from dual union all
select 'AP3', to_date('25/12/2021', 'dd/mm/yyyy'), to_date('5/1/2022', 'dd/mm/yyyy') from dual union all
select 'AP4', to_date('1/1/2022', 'dd/mm/yyyy'), to_date('15/1/2022', 'dd/mm/yyyy') from dual union all
select 'AP5', to_date('6/1/2022', 'dd/mm/yyyy'), to_date('21/1/2022', 'dd/mm/yyyy') from dual union all
select 'AP6', to_date('28/1/2022', 'dd/mm/yyyy'), to_date('13/2/2022', 'dd/mm/yyyy') from dual
)
select *
from
(
select code code, dates1 dates1_a, dates2 dates2_a, 'table_a' tbl_name
from table_a
union all
select code code, dates1 dates1_b, dates2 dates2_b, 'table_b' tbl_name
from table_b
)
order by least(dates2_a), least(dates1_a);

Running the above sql query, there are some differences in the ordering.
Is there any way to get the desired final list?

Notes:

  1. I use OracleDB v11g.
  2. The two initial lists may not have the same number of records or one of them may have no record.
  3. In the final list, the ordering of codes in list 1 remains the same as in its first(initial) list. To make it more clearer, there is no possibility to have for example 'B2' before the 'B1' or 'B5' after 'B6'. If you note the desired final list, you can see that the ordering of the list1 is the same as in the final list - simply some record codes of list 2 have been inserted in between .
    The same is also true for the list 2.

Thanks,
Sim

This post has been answered by Stew Ashton on Feb 17 2022
Jump to Answer
Comments
Post Details
Added on Feb 15 2022
17 comments
1,273 views