Получите самые длинные и короткие «цепочки» в MySQL? - PullRequest
0 голосов
/ 16 марта 2020

Рассмотрим следующую схему:

create table Operation(id integer, name varchar(100));
create table Pipeline(operation_in integer, operation_out integer);

Pipeline имеет внешние ключи для Operations, поэтому конвейеры каким-то образом связаны. operation_out обнуляется. Как получить имена операций как в самой длинной, так и в самой короткой цепочке конвейеров, используя MySQL?

Операции выглядят так:

INSERT INTO Operation VALUES (1, 'operation one');

В то время как конвейеры выглядят примерно так:

INSERT INTO Pipeline VALUES (1, 2);
INSERT INTO Pipeline VALUES (2, 4);
INSERT INTO Pipeline VALUES (4, 7);
INSERT INTO Pipeline VALUES (7, NULL);

Т.е. здесь будут цепочки операций с ID 1, 2, 4, 7 и ожидаемым результатом в соответствии с:

"operation one", "operation two", "operation four"...

После нескольких часов исследований я Я не совсем уверен, какое решение я ищу.

Любая версия MySQL применима.

1 Ответ

1 голос
/ 16 марта 2020

В MySQL 8.x вы можете использовать рекурсивный CTE, чтобы найти нужные вам цепочки.

Например:

with recursive
a as (
  select
    p.operation_in,
    p.operation_out as current_out,
    o.name as op_names,
    concat('', p.operation_in) as chain,
    1 as size
  from pipeline p
  join operation o on o.id = p.operation_in
  where not exists (
    select 1 from pipeline p2 where p2.operation_out = p.operation_in
  )
  union all
  select
    a.operation_in,
    p.operation_out,
    concat(op_names, ', ', o.name),
    concat(chain, ',', p.operation_in),
    size + 1
  from a
  join pipeline p on p.operation_in = a.current_out
  join operation o on o.id = p.operation_in
),
chains as (
  select * from a where current_out is null
)
select op_names, chain, size
from chains
where size = (select max(size) from chains)  -- finds the longest one
   or size = (select min(size) from chains); -- finds the shortest one

Результат:

op_names                           chain    size
---------------------------------  -------  ----
op-nine, op-six                    9,6         2
op-one, op-two, op-four, op-seven  1,2,4,7     4

Используемый мной скрипт данных:

create table operation (id integer, name varchar(100));
create table pipeline (operation_in integer, operation_out integer);

insert into operation values (1, 'op-one');
insert into operation values (2, 'op-two');
insert into operation values (4, 'op-four');
insert into operation values (6, 'op-six');
insert into operation values (7, 'op-seven');
insert into operation values (9, 'op-nine');

insert into pipeline values (1, 2);
insert into pipeline values (2, 4);
insert into pipeline values (4, 7);
insert into pipeline values (7, null);
insert into pipeline values (9, 6);
insert into pipeline values (6, null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...