Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
scoreZ
Guest |
Коллеги, не подскажете, как решить задачку: в двух таблицах есть элементы, коллизий с которыми быть не должно. Элементы не полностью совпадают, имеется некая база, начиная с которой идёт инкремент. Но дело в том, что доступ к редактированию таблиц (добавление и удаление записей) есть у пользователя и поэтому полагаться на то, что коллизии не будет я не могу - вдруг пользователю захочется создать элементы, с которыми она произойдёт. Такой вот пример:declare @T1 table (M varchar(10)); -- интересующие нас элементы с коллизией имеют базу 100000 (но не обязательно должны иметь формат 1ххххх, после 199999 будет 200000, 200001 и т.д.) declare @T2 table (N varchar(10)); -- полностью аналогично предыдущему, но база 200000 declare @Z table (X int); -- в эту таблицу будут записываться последовательные числа, не имеющие коллизий с базовыми значениями таблиц @T1 и @T2 insert into @T1 values ('100005'); insert into @T2 values ('200003'); insert into @T2 values ('200004'); insert into @T2 values ('200006'); insert into @T1 values ('100009'); insert into @Z values (2); -- следующим числом @Z.X должно быть 7 -- т.к. 2 уже было, 3 и 4 находятся в @T2, 5 в @T1, 6 в @T2 -- но не 10 - так, конечно, было бы проще, но нужно вклиниться между занятыми 6 и 9 insert into @Z values ((select isnull(max(X),0)+1 from @Z /*where ??? @T1.M-100000 ??? @T2.N-200000 ??? */)); select * from @Z; SQL Server 2008 R2. Функцию очень не хотелось бы использовать, лучше всего один запрос. У меня была идея заджоинить выборки с таблиц @T1 b @T2 и автоинкремент, получить первое значение где M и N будут null... Но я не знаю, как сюда привязать автоинкремент. По номеру строки как-то не получится - у меня же должны быть "дыры", а если в обоих таблицах нет нужного индекса - и строки не будет... Чувствую, что должно быть правильное решение, но я его как-то не вижу... |
8 авг 17, 18:57 [20709289] Ответить | Цитировать Сообщить модератору |
Гавриленко Сергей Алексеевич Member Откуда: Moscow Сообщений: 37155 |
Завести таблицу с числавми и уже из нее "выдавать" значения в @T1/@T2/.../@TN (с соттветствущей отметкой, куда "выдано")
Сообщение было отредактировано: 8 авг 17, 19:02 |
8 авг 17, 19:02 [20709296] Ответить | Цитировать Сообщить модератору |
scoreZ
Guest |
Гавриленко Сергей Алексеевич, так собственно таблицы @Z для этого и служит. Чтобы выдавать значения для @T1 и @T2. Другое дело что в последние таблицы пишу не только я, но и пользователи. И они как раз могут случайно вставить запись, которая приведёт к коллизии. |
8 авг 17, 19:24 [20709325] Ответить | Цитировать Сообщить модератору |
Remind Member Откуда: UK Сообщений: 523 |
scoreZ, Что-то типа такого? declare @max int; select @max = max(X) from @z ;with cte(Y) as ( select @max union select M-100000 from @T1 where M > @max + 100000 union select N-200000 from @T2 where N > @max + 200000 ), rn as ( select *, rn = row_number() over (order by Y) + @max - 1 from cte ) select isnull(min(rn), (select max(Y) from cte)) from rn where rn <> Y |
8 авг 17, 20:39 [20709433] Ответить | Цитировать Сообщить модератору |
Remind Member Откуда: UK Сообщений: 523 |
select max(Y) + 1 from cteконечно же |
8 авг 17, 20:47 [20709451] Ответить | Цитировать Сообщить модератору |
scoreZ
Guest |
Remind, да, это оно, премного благодарствую! Вот только иногда выдавало значение с коллизией, например (это полный список инсертов, замещающий те, что в примере): insert into @T2 values ('200008'); insert into @Z values (8); --результат 7 insert into @T1 values ('100005'); insert into @T2 values ('200003'); insert into @T2 values ('200004'); insert into @T2 values ('200006'); insert into @Z values (2); --результат 6 Разобрался в логике - походу, проблема решается так: select isnull(min(rn), (select max(Y) from cte)[b]+1[/b]) from rn where rn <> Y Ещё раз спасибо за помощь! |
8 авг 17, 21:01 [20709471] Ответить | Цитировать Сообщить модератору |
scoreZ
Guest |
О, болдом в коде нельзя выделять, не подумал )) |
8 авг 17, 21:02 [20709473] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |