#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;