Удаление (группирование по) массивов, которые являются подмножествами самого большого массива - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть набор данных, который выглядит следующим образом:

| path              |
|-----------------  |
| {16,13}           |
| {16,85}           |
| {16,85,1}         |
| {16,85,2}         |
| {16,85,15}        |
| {16,85,80}        |
| {16,85,80,1}      |
| {16,85,80,63}     |
| {16,85,80,63,1}   |

Столбец пути представляет собой своего рода иерархический путь через граф от одного узла к другому узлу.Я пытаюсь свернуть каждый путь вниз в самые длинные пути от корневых до конечных узлов - следует отметить, что порядок элементов важен ({1, 2, 3}! = {3, 2, 1}).

Например:

  • Путь {16, 13} - это самый длинный путь, содержащий 16 и 13 в этом порядке , поэтому он остается.
  • Путь {16, 85} не самый длинный, так как есть более длинный путь, содержащий эти элементы в этом порядке , а именно {16, 85, 2}.Поэтому строка с {16, 85} должна быть отброшена из набора результатов, а {16, 85, 2} должна быть сохранена, так как она окажется самой длинной.
  • И т.д.с каждой второй строкой

Таким образом, результирующий набор выглядит следующим образом:

| path              |
|-----------------  |
| {16,13}           |
| {16,85,1}         |
| {16,85,2}         |
| {16,85,15}        |
| {16,85,80,1}      |
| {16,85,80,63,1}   |

Я даже не уверен, с чего начать, все, что я пробовал, провалилось.

Я обнаружил, что есть нечто, называемое оператором массива @>, но не знаю, как его применить.

Есть ли разумный запрос для этого?Любая помощь будет отличной.Спасибо!

1 Ответ

0 голосов
/ 23 сентября 2018

Я думаю, вы хотите оператор "не содержит".Итак, вы можете сделать:

select p.*
from paths p
where not exists (select 1
                  from paths p2
                  where p2.path @> p.path and p2.path <> p.path
                 );

Я не обещаю, что это эффективно, но оно должно хорошо работать на маленьком столе.

РЕДАКТИРОВАТЬ:

Дляобрабатывать порядок, один из подходов заключается в преобразовании в строку:

select p.*
from paths p
where not exists (select 1
                  from paths p2
                  where array_to_string(p2.path, ',') like array_to_string(p.path, ',') || ',%' 
                 );
...