Вероятно, есть много способов сделать это, но для меня это выглядит как проблема, которую лучше всего решить с помощью CONNECT BY.
Я создал таблицу с именем "mytable" с вашими примерами данных и написал пример запроса, который возвращает ожидаемые результаты.
Outline:
- Мы начинаем с любой строки и подключаемся к другой строке на основе того же идентификатора или PARAM.
- Использование ключевое слово NOCYCLE предотвращает циклы.
- Функция CONNECT_BY_ ROOT выбирает значение из строки, с которой мы начали.
- Однако внутренний запрос возвращает больше строк, чем мы хотим. Например, [4, D] имеет [3, D] как «root», но мы хотим отследить его как можно дальше до [1, A].
- Итак, по порядку чтобы уменьшить строки, мы используем функцию row_number () analyti c для нумерации каждого "root" для данной пары id / param.
- Затем мы выбираем только те результаты, где номер строки (r1 ) равен единице.
- И, наконец, результаты сортируются по значениям id и param.
select id, param, rootid||'-'||rootparam as "Expected result" from (
select row_number() over (partition by id, param order by rootid, rootparam) r1,
rootid, rootparam, id, param from (
select connect_by_root(id) rootid, connect_by_root(param) rootparam,
id, param
from mytable
connect by nocycle (prior param =param and prior id <> id)
or (prior id = id and prior param <> param)
order by connect_by_root(id), connect_by_root(param)
)
) where r1 = 1
order by to_number(id), param
Отказ от ответственности: Это пример для информационных целей и не предназначен для оптимизации или оптимизации SQL. Неуместно использовать как есть для вашего производственного приложения или домашнего задания. Используйте EXPLAIN PLAN, чтобы увидеть, насколько оптимизатор оправдан, и если у вас большие объемы данных и вы беспокоитесь о скорости, измерьте время, затрачиваемое вашими альтернативными запросами, а не угадывайте, что быстрее.
Вот инициализация для тестовых данных:
create table mytable as
select '1' ID,'A' PARAM from dual -- 1-A
union all select '1' ID,'C' PARAM from dual -- 1-A
union all select '2' ID,'A' PARAM from dual -- 1-A
union all select '2' ID,'C' PARAM from dual -- 1-A
union all select '2' ID,'D' PARAM from dual -- 1-A
union all select '3' ID,'D' PARAM from dual -- 1-A
union all select '4' ID,'AA' PARAM from dual -- 1-A
union all select '4' ID,'D' PARAM from dual -- 1-A
union all select '4' ID,'K' PARAM from dual -- 1-A
union all select '4' ID,'T' PARAM from dual -- 1-A
union all select '4' ID,'W' PARAM from dual -- 1-A
union all select '4' ID,'Z' PARAM from dual -- 1-A
union all select '5' ID,'W' PARAM from dual -- 1-A
union all select '6' ID,'W' PARAM from dual -- 1-A
union all select '7' ID,'T' PARAM from dual -- 1-A
union all select '8' ID,'AA' PARAM from dual -- 1-A
union all select '10' ID,'FF' PARAM from dual -- 10-FF
union all select '15' ID,'G' PARAM from dual -- 15-G
union all select '99' ID,'FF' PARAM from dual -- 10-FF