:: Игры Разума
Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Это не про внутренние ID значения в базе данных, а внешние. Немного искусственный пример:
- компания заключает договора с клиентами
- договора имеют целочисленный номер
- желательно экономить номера
- допускается повторно использовать незадействованные номера ("дырки", далее Д)
Вот задача и состоит в поиске этих дырок в БД.

Итак, что есть Д? Это последовательность занятых номеров (хотя бы один занятый номер), а за ним - последовательность незанятых, условленной минимальной длины (ну, потому-что 1-2 незанятых номера - это у нас норма, а >10 это выделенный диапазон номеров, но по разным причинам - неиспользованный) - такая последовательность далее названа "ступенька вниз".

Далее, как определить наличие Д: это такая серия: 1 задействованный номер + несколько незадействованых. Оказалось, что работает технология из электроники - "цифровой фильтр с линией задержки (далее ЛЗ)" - т.е. мы (при помощи ЛЗ приводим нужные номера в одну точку, и суммируем эти приведенные номера на предмет события, что должно быть: 1 присутстсвующий номер, AND столько-то отсутствующих. ЛЗ в данном случае - это всего лишь оператор "номер=номер+-1". Эти операции ЛЗ и суммирования оказалось можно выполнить в SQL-SELECT операторе, в его WHERE (т.к. WHERE применяется к каждой записи таблицы)

Вот получился код, как ни странно, он ищет Д, даже правильно (ну, у нас есть бумажный журнал Д, вот она его повторят, и правильно ищет границы занятости номеров в выделенных агентам диапазонах номеров)... далее см. комментарии в коде...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Равиль
Автор

Сообщений: 6555
Откуда: Уфа
Дата регистрации: 01.08.2003
Олег, привет - ничего не понимаю в Селектах

ps убрал лишние строчки


------------------
Тяжело согнать курсором муху с монитора ...




Исправлено 2 раз(а). Последнее : Равиль, 22.12.13 18:15
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Равиль, не вьехал, что значит "я не понимаю в SELECT"-х, Ты это должен прекратить, и наоборот, говорить, что мол, ваши селекты д.б. более правильные, вот таие типа ...

Я предложл полуматематическое "решение", я не смог санализировать корректность механики счета дырок, хотел услышать мнение... хммм...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Равиль
Автор

Сообщений: 6555
Откуда: Уфа
Дата регистрации: 01.08.2003
of63
Равиль, не вьехал, что значит "я не понимаю в SELECT"-х, Ты это должен прекратить, и наоборот, говорить, что мол, ваши селекты д.б. более правильные, вот таие типа ...

Когда-то тестили скорость работы селектов с аналогичными решениями без них - селекты частенько проигрывают по времени исполнения.
Думаю у сторонников селектов есть шанс опровергнуть это утверждение

of63
.. Я предложл полуматематическое "решение", я не смог санализировать корректность механики счета дырок, хотел услышать мнение... хммм...

Значит решил "поверить музой алгебру" - тебе это удалось


------------------
Тяжело согнать курсором муху с монитора ...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Равиль, рад тебя видеть, я блин, блин... "алгебры множеств Ли", ты не представялешь, как это интересно !Все интересно, что и пытаюсь показать... )))
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Равиль
Автор

Сообщений: 6555
Откуда: Уфа
Дата регистрации: 01.08.2003
of63
Равиль, рад тебя видеть, я блин, блин... "алгебры множеств Ли", ты не представялешь, как это интересно !Все интересно, что и пытаюсь показать... )))

Я тоже рад !
Олег, чтоб заценить твой подход нужно потрогать практический работающий пример.


------------------
Тяжело согнать курсором муху с монитора ...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Ну, я стеснняюсь, инда ... Про потенциалы?
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Равиль
Автор

Сообщений: 6555
Откуда: Уфа
Дата регистрации: 01.08.2003
of63
.. Про потенциалы?
а я в электронике без потенции ...


------------------
Тяжело согнать курсором муху с монитора ...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
я тоже, хз, хочулия, могулия, но не важно! Электроники и без нас выживут )))
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Пытался найти, что-то приличсчисвующеке слуявай, Равиль, привет )))
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Это как www.youtube.com
все5 не так "http://www.youtube.com/watch?v=Qm9gUNbSqlk"
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Равиль
Автор

Сообщений: 6555
Откуда: Уфа
Дата регистрации: 01.08.2003
Олег приезжай в Екатеринбург в мае!


------------------
Тяжело согнать курсором муху с монитора ...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
[color=Red][/color]ВсетакиЮ нужно лично общнуться, вот не вижу продолжненияч п-разговора.

Оказалось, в аскен, не работаюи интуитивные и-ы"...Как же достучаться до Равиля...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Приехать не реально, и смысла не вижу, (все умирает, а в процессе смерти - нет смысла мотаться по стране)
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Боянистый вопрос...
LOCAL lnMaxInterval
lnMaxInterval = 10
CREATE CURSOR test (ID i)
INSERT INTO test (ID) VALUES (1)
INSERT INTO test (ID) VALUES (2)
INSERT INTO test (ID) VALUES (4)
INSERT INTO test (ID) VALUES (5)
INSERT INTO test (ID) VALUES (6)
INSERT INTO test (ID) VALUES (9)
INSERT INTO test (ID) VALUES (10)
INSERT INTO test (ID) VALUES (11)
INSERT INTO test (ID) VALUES (12)
INSERT INTO test (ID) VALUES (120)
SELECT p1.Start, p2.End ;
FROM ;
(SELECT RECNO() rn, Start ;
FROM (SELECT t1.ID + 1 Start ;
FROM test t1 ;
LEFT JOIN test t2 ;
ON t1.ID = t2.ID - 1 ;
WHERE t2.ID IS NULL) a1) p1 ;
INNER JOIN ;
(SELECT RECNO() - 1 rn, End ;
FROM (SELECT t1.ID - 1 End ;
FROM test t1 ;
LEFT JOIN test t2 ;
ON t1.ID = t2.ID + 1 ;
WHERE t2.ID IS NULL) a2) p2 ;
ON p1.rn = p2.rn ;
WHERE p2.End - p1.Start < m.lnMaxInterval


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Блин, Игорь, какого года баян?
Я тебе вобще скажу - ты убиваешь положительное самомнение слушателей тебя... Ты хоть под..и немного

Вобще - от отсутсвия самоценности - убиться можно... Тебе сколько лет?



Исправлено 2 раз(а). Последнее : of63, 22.12.13 22:50
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Равиль
Автор

Сообщений: 6555
Откуда: Уфа
Дата регистрации: 01.08.2003
Игорь, у меня твой запрос выдает нечто ... или так задумано ))


------------------
Тяжело согнать курсором муху с монитора ...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Равиль
Автор

Сообщений: 6555
Откуда: Уфа
Дата регистрации: 01.08.2003
Равиль
Игорь, у меня твой запрос выдает нечто ... или так задумано ))

Игорь, извиняюсь - сейчас глянул еще - запрос правильно отрабатывает - не обратил внимание, что у тебя в условии стоит знак "меньше" (< m.lnMaxInterval), из контекста задачи ожидалось условие "больше".


------------------
Тяжело согнать курсором муху с монитора ...
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
У меня он выдаёт не "нечто", а курсор с 2 записями. Работает, естественно, только в VFP9, т.к. тут сплошные подзапросы во FROM. В старых версиях то же самое нужно делать отдельными запросами (5 шт. выйдет - ну или 3 запроса и 2 UPDATE для прописывания "номеров строк" - т.к. RECNO() в многотабличном запросе не работает).
start end
3     3
7     8
Что соответствует поставленному условию поиска пропусков номеров. Интервал "дырок" 13-119 не попадает т.к. он "слишком большой".


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Поиск "дырок" в (автоинкрементных) номерах ID
Равиль
Автор

Сообщений: 6555
Откуда: Уфа
Дата регистрации: 01.08.2003
Igor Korolyov
У меня он выдаёт не "нечто", а курсор с 2 записями ...
Да, это я успел заметить, см. выше.
Интересно было сравнить скорость - накидал тест - у меня запрос работает в 1,4 - 1,5 раза медленнее скана:
Часть текста скрыта
Set Safety Off
Clear
Local lnTestCount, m.t
lnTestCount = 10 && кол-во тестов
Local lnCount
lnCount = 100000 && Задаем размер тестовой таблицы (число записей)
Local nTime1, nTime2
Store 0 To nTime1, nTime2
_ClipText = "Суммарное время : "+CHR(13)
? "Суммарное время : "
For m.t = 1 To m.lnTestCount
Wait Window " Тест № "+Transform(m.t) Nowait
m.nTime1 = m.nTime1 + TestTime(1, lnCount)
m.nTime2 = m.nTime2 + TestTime(2, lnCount)
? m.t, m.nTime1, m.nTime2
_ClipText = _ClipText + TRANSFORM(m.t)+CHR(9)+TRANSFORM(m.nTime1)+CHR(9)+TRANSFORM(m.nTime2)+CHR(13)
Next
_ClipText = _ClipText + "Среднее время : "+CHR(9)+TRANSFORM(m.nTime1/m.lnTestCount)+CHR(9)+TRANSFORM(m.nTime2/m.lnTestCount)+CHR(13)
? "Среднее время : ", m.nTime1/m.lnTestCount, m.nTime2/m.lnTestCount
Function TestTime
*****************
Lparameters tnTipTest,; && 1 - вариант без запроса, 2 - запрос
tnCount && размер таблицы
*!* Каждый раз готовим новые таблицы
Use In Select("tTest0")
Use In Select("tTest1")
Use In Select("tTest2")
Use In Select("tTest")
Create Table tTest0 (Id i, lPropusk l) && таблица Эталон (без пропусков)
Create Table tTest1 (Id i) && таблица Случайная (с пропусками)
Create Table tTest (Id1 i, Id2 i, iDelta i) && таблица Отчет о пропусках
=Rand(-1)
Local i, lnMaxInterval
lnMaxInterval = 2
For m.i = 1 To m.tnCount && Генерим таблицы
Insert Into tTest0 (Id) Values (m.i)
Insert Into tTest1 (Id) Values (m.tnCount*Rand())
Next
Select tTest1
Index On Id Tag Id Unique
Copy To tTest2
Use In Select("tTest1")
Use tTest2 Alias tTest1 Exclusive && Таблица с пропусками ID
Local m.tStart
tStart = Seconds()
*!* Конец общей части
Do Case
Case m.tnTipTest = 1
Index On Id Tag Id Additive
Select tTest0
Set Relation To Id Into tTest1
Replace All lPropusk With .T. For Eof("tTest1")
Set Relation Off Into tTest1
Index On lPropusk For lPropusk Tag lP
Go Top
Local m.lnStart, m.lnLast, m.lnEnd
Store Id To m.lnStart, m.lnLast, m.lnEnd
Scan
If Id > m.lnLast + m.lnMaxInterval
m.lnEnd = m.lnLast
Insert Into tTest (Id1, Id2, iDelta) Values (m.lnStart, m.lnEnd, m.lnEnd - m.lnStart + 1)
m.lnStart = Id
Endif
m.lnLast = Id
Endscan
*!* и в конце
If Id > m.lnLast + 1
m.lnEnd = m.lnLast
Insert Into tTest (Id1, Id2, iDelta) Values (m.lnStart, m.lnEnd, m.lnEnd - m.lnStart + 1)
Endif
*!* Select tTest1
*!* Go Top
*!* Browse Last Title "Таблица с пропусками" Nowait
*!*
*!* Select tTest
*!* Go Top
*!* Browse Last Title "Таблица отчет" Nowait
Case m.tnTipTest = 2
*!* CREATE CURSOR tTest1 (ID i)
*!* INSERT INTO tTest1 (ID) VALUES (1)
*!* INSERT INTO tTest1 (ID) VALUES (2)
*!* INSERT INTO tTest1 (ID) VALUES (4)
*!* INSERT INTO tTest1 (ID) VALUES (5)
*!* INSERT INTO tTest1 (ID) VALUES (6)
*!* INSERT INTO tTest1 (ID) VALUES (9)
*!* INSERT INTO tTest1 (ID) VALUES (10)
*!* INSERT INTO tTest1 (ID) VALUES (11)
*!* INSERT INTO tTest1 (ID) VALUES (12)
*!* INSERT INTO tTest1 (ID) VALUES (120)
*!*
Select p1.Start, p2.End ;
FROM ;
(Select Recno() rn, Start ;
FROM (Select t1.Id + 1 Start ;
FROM tTest1 t1 ;
LEFT Join tTest1 t2 ;
ON t1.Id = t2.Id - 1 ;
WHERE t2.Id Is Null) a1) p1 ;
INNER Join ;
(Select Recno() - 1 rn, End ;
FROM (Select t1.Id - 1 End ;
FROM tTest1 t1 ;
LEFT Join tTest1 t2 ;
ON t1.Id = t2.Id + 1 ;
WHERE t2.Id Is Null) a2) p2 ;
ON p1.rn = p2.rn ;
WHERE p2.End - p1.Start > m.lnMaxInterval ;
INTO Table tTest
Endcase
Return Seconds()-m.tStart
Результат:
Суммарное время :
1 0,230 0,323
2 0,462 0,646
3 0,694 0,971
4 0,925 1,293
5 1,158 1,615
6 1,387 1,936
7 1,623 2,268
8 1,854 2,604
9 2,085 2,932
10 2,319 3,260
Среднее время : 0,2319 0,3260




------------------
Тяжело согнать курсором муху с монитора ...




Исправлено 1 раз(а). Последнее : Равиль, 23.12.13 16:31
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 13 (Гостей: 13)

© 2000-2024 Fox Club 
Яндекс.Метрика