Найти следующий неиспользуемый идентификатор в таблице SQL, которая имеет непрерывные диапазоны
У меня есть две таблицы, подобные следующим:
TABLE1:
=======
somid, tobeupdated
1 , null
2 , null
3 , null
10 , null
TABLE2:
=======
rangeofids
2
3
9
10
11
12
13
Я должен обновить TABLE1.tobeupdated (или обнаружил, что его 'должно быть значением) на основе следующих критериев:
- если
TABLE1.somid NOT exists in TABLE2.rangeofids
, то ожидаемый результат: tobeupdated =TABLE1.somid
- еще найти следующий доступный (или неиспользованный)
TABLE2.rangeofids
что больше, чемTABLE1.somid
Итак, ожидаемые значения: bu
TABLE1:
=======
somid, tobeupdated
1 , 1
2 , 4
3 , 4
10 , 14
Я очень старался, но самое простое решение, которое я нашел, - это создание временной таблицы с полной последовательностью идентификаторов (из 1
в max(rangeofids)+1
) MINUS TABLE2.rangeofids
так что я могу найти MIN(TMPTABLE.id) where TMPTABLE.ID > TABLE1.somid
,
Но разве нет лучшего решения (без временной таблицы)?
Примечание: я не могу создавать процедуры / функции и т. Д., Поэтому это должен быть стандартный (Oracle 10) SQL.
1 ответ
Это моя попытка.
Сначала мы должны решить, используя только table2, какое значение должно возвращаться после нахождения значения там.
select rangeofids,
candidate,
nvl(candidate,lead(candidate ignore nulls) over (order by rangeofids)) as full_candidate
from (
select rangeofids, case when dist=1 then null else rangeofids+1 end as candidate
from (
select rangeofids,
lead(rangeofids) over (order by rangeofids) - rangeofids as dist
from table2
)
);
После этого merge into table1 with
Выбор ниже решит проблему:
select someid, nvl(full_candidate, someid)
from table1 a
left join (
--the above query
) b
on a.someid = b.rangeofids;