Как связать строки на основе ключа и предыдущего ключа без нескольких объединений

#sql #oracle

Вопрос:

У меня есть данные в таблице, которая выглядит как:

ID previous_id значение
01 NULL
02 01
03 02
04 03
.. ..

Я хотел бы установить значение для строки на основе значения строки с предыдущим идентификатором, равным этому идентификатору строк. Например, если строка с ID = 04 имеет значение 1, я бы хотел, чтобы строка с предыдущим ID = 04 также имела значение 1, что, в свою очередь, приведет к тому, что строка с предыдущим ID = 03 будет иметь значение 1 и так далее.

У меня нет заданного количества подключенных строк, а идентификаторы являются идентификаторами GUID.

Есть ли способ выполнить такую функцию без использования временных таблиц, где она будет проверять значение строки с предыдущим идентификатором, равным идентификатору строк, а затем присваивать значение на основе этого значения строк в том же столбце.

псевдо SQL для рекурсивной логики, которую я представляю: случай, когда не существует (строка с предыдущим идентификатором, равным ID), тогда значение randomColumn else строки с предыдущим идентификатором end в качестве значения

Комментарии:

1. Похоже LAG , что аналитическая функция может быть тем, что вам нужно, или, может FIRST_VALUE быть, или LAST_VALUE в зависимости. Пожалуйста, отредактируйте свой вопрос, чтобы включить фактические данные вместе с ожидаемым результатом. 1 Например, откуда берется значение, о котором вы говорите?

2. PL / SQL — это язык программирования. Запросы — это SQL. Обновленный вопрос и теги.

Ответ №1:

Вы можете получить результаты, которые вы запросили напрямую, используя одно простое соединение:

 select c.id, c.prev_id, p.val 
 from tbl c
 left join tbl p 
   on (c.prev_id = p.id) 
order by c.id;
 

Функции Lead / Lag завершаются сбоем, поскольку они зависят от последовательности, нет ничего, что могло бы гарантировать последовательность в ваших данных, поскольку идентификаторы являются идентификаторами GUID.

Однако это еще многое требует ответа. Вы установили иерархическую связь, поэтому должен ли результат отражать эту связь? С одной ветвью и с упорядоченным идентификатором: prev_id это в принципе не требует дополнительной работы. Но иерархии редко поддерживают такой порядок — они, как правило, становятся беспорядочными. Чтобы разгадать это, вам нужно конкретно обратиться к самой иерархии. Лучший способ добиться этого (в Oracle) — начать с … подключиться с помощью … (см. Демонстрацию. Имеет оба)

 select id
     , prev_id
     , (select val 
          from tbl t
         where t.id = h.prev_id
       ) 
  from (select id, prev_id
          from tbl 
        connect by prev_id = prior id 
          start with prev_id is null 
        ) h;