Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Manonia Member Откуда: Иркутск Сообщений: 112 |
Привет! задача найти свободные id, при чём нужно учитывать интервалы 0..10..20..30..40. Например, нужно сначала проверить интервал от 0 до 10, потом от 30 до 40 и т.п(шаг = 30). Соотвтественно, может быть ситуация, когда от 0 до 10 всё занято, переходим на второй интервал и берем 31(30 зарезервирован). Решение ниже довольно компактное, но оно не покрывает кейс, если у нас вообще ничего не занято из интервала... конечно тут наверное можно прикрутить if exist, хочется просто красивее решение. И еще вопрос, когда ввожу @freeCode, то в любом случае всегда возвращается число. Например, интервал от 0 до 10 занят, @freeCode вернётся 11. Поэтому использую проверку declare @freeCode int = null, @minRange int, @maxRange int, @step int = 30 declare @counter int, @intCnt int set @counter = 10 set @intCnt = 0 set @minRange = 0 set @maxRange = 10 while (@intCnt < @counter) begin select TOP 1 @freeCode = ID + 1 from @Route AS ESR where ESR.ID between @minRange and @maxRange and (select 1 from @Route AS ESR2 where ESR2.ID between @minRange and @maxRange and ESR2.ID = (ESR.ID + 1)) is null and (select 1 from @Route2 as GR where GR.ID between @minRange and @maxRange and GR.ID = (ESR.ID + 1)) is null order by ESR.ID if (@freeCode between @minRange and @maxRange) begin break end set @minRange = @minRange + @step --0, 30, 60 set @maxRange = @maxRange + @step -- 10, 40, 70 set @intCnt = @intCnt + 1 end |
19 мар 15, 17:20 [17406573] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Все ? Или один первый ? Или диапазон(ы) ? |
||
19 мар 15, 17:24 [17406606] Ответить | Цитировать Сообщить модератору |
msLex Member Откуда: Сообщений: 8694 |
нужны 1. таблица всех возможных номеров (AllNumbers) 2. таблицы всех периодов (AllPeriods) select top 1 n.id from AllNumbers n inner join AllPeriods p on n.id between p.min_id and p.max_id where not exists ( select * from table @Route r where r.id = n.id ) order by n.id |
19 мар 15, 17:28 [17406627] Ответить | Цитировать Сообщить модератору |
Manonia Member Откуда: Иркутск Сообщений: 112 |
Glory, нужно найти один айди, первый свободный. Например: 0...10...20...30 Если есть "дырка" в 0..10(0, 1, 2, 4, 6, 7) - достаем это значение(3 в этом случае). Если все занято, то идем на второй диапазон и ищем там либо "дырки", либо берем первое значение, если ничего нет. msLex, решение красивое, но проблема со 2 таблицей, rang'ы по условию определяются...AllNumbers - тут вообще ограничений нет... |
19 мар 15, 18:51 [17406870] Ответить | Цитировать Сообщить модератору |
msLex Member Откуда: Сообщений: 8694 |
вместо таблицы с AllPeriods добавьте если условие в where по id n.id % @step between 0 and 10 а таблицу AllNumbers сгенерити уж один раз, миллионов на 100, и кластерный индекс по id сделайте. |
||
19 мар 15, 19:17 [17406920] Ответить | Цитировать Сообщить модератору |
Manonia Member Откуда: Иркутск Сообщений: 112 |
msLex, спасибо! Нашла как рекомедуют вставлять данные: insert intoMyTable(ID) select top(6400000) 0 from sys.all_objects as o1 cross join sys.all_objects as o2 cross join sys.all_objects as o3 И так на нескольких ресурсах. Неужели нет способа без sys.all_objects? ну и без while конечно. |
19 мар 15, 20:10 [17407068] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
Или вы про создание таблицы AllNumbers? Её же один раз нужно создать, сделайте с sys.all_objects. |
||
19 мар 15, 20:18 [17407089] Ответить | Цитировать Сообщить модератору |
Добрый Э - Эх
Guest |
Manonia, облегче жизнь себе и другим форумчанам - воспользуйся формулой: "репрезентативный юзабильный набор тестовых данных" + "желаемый вид результата на них" = "много разных решений от участников форума". :) |
20 мар 15, 03:44 [17407864] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |