Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.04.05;
Скачать: CL | DM;

Вниз

Поиск "дырки" в записях   Найти похожие ветки 

 
Maacheba   (2009-02-12 19:05) [0]

Есть таблица, назовем ее "MyTable", формат:

Number | FlagDeleting

Number - число, FlagDeleting - тоже число, если равно 1 - то запись считается уничтоженной в запросах (но физически из таблицы не удаляется).

Задача: найти первую свободную "дырку" в последовательности Number среди не помеченных на удаление записях.

Пример:

Number | FlagDeleting
================
1         |  0
6         |  0
4         |  0
2         |  0

Правильный ответ: 3

Еще пример:

Number | FlagDeleting
================
1         |  0
2         |  1
3         |  0
4         |  0

Правильный ответ: 2

Чтобы найти дырку - с успехом срабатывает такой код:

SELECT MyTable.Number + 1 from MyTable left join
 MyTable m on (MyTable.Number + 1 = m.Number) where "
 (m.Number is null) and (MyTable.Number+1 > X)


Где "X" - фактически задает тот лимит с которого искать дырку. Если X = 0, то дырка начинает искаться с числа 1, если задать X=5, то дырка начинает искаться 6 и т.д.

Вопрос в том, что нужно учесть столбец FlagDeleting, помеченые как удаленные записи просто не рассматривать. Если делать так:

SELECT MyTable.Number + 1 from MyTable left join
 MyTable m on (MyTable.Number + 1 = m.Number) where "
 (m.Number is null) and (MyTable.Number+1 > X) and (MyTable.FlagDeleting=0)


То такой запрос возвращает NULL.
Если условие MyTable.FlagDeleting=0 заменить на m.FlagDeleting=0 или их сочетание - тоже самое.

Не понимаю, почему так происходит и как это исправить?

P.S. База - SQLite


 
Palladin ©   (2009-02-13 08:04) [1]

Number надеюсь не используется как первичный ключ?


 
Jack128_   (2009-02-13 08:35) [2]


> m.FlagDeleting=0

это условие помести в

left join
MyTable m on (MyTable.Number + 1 = m.Number) and m.FlagDeleting<>0


 
Jack128_   (2009-02-13 08:38) [3]


> left join
> MyTable m on (MyTable.Number + 1 = m.Number) and m.FlagDeleting=0


Хотя навскидку моно и оставить в where, примерно в таком виде:

where (MyTable.Number+1 > X) and ((m.Number is null) or (MyTable.FlagDeleting=0))


 
Jack128_   (2009-02-13 09:23) [4]

Блин.

>
> where (MyTable.Number+1 > X) and ((m.Number is null) or
> (m.FlagDeleting=0))

вобщем сам разберешся, смысл, надеюсь понял..


 
Johnmen ©   (2009-02-13 09:45) [5]


> Maacheba   (12.02.09 19:05) 

Просто в условие соединения добавить and (m.FlagDeleting=0)


 
Maacheba   (2009-02-13 11:57) [6]

Никто не поможет?


 
Maacheba   (2009-02-13 12:11) [7]

Ух, почему-то при просмотре ветки она закешировалась, думал нет новых ответов...
Спасибо всем за помощь!


 
Maacheba   (2009-02-13 12:12) [8]


> Number надеюсь не используется как первичный ключ?

нет, конечно.


 
MsGuns ©   (2009-02-13 12:14) [9]

Такой запрос написать не проблема, но он будет выполняться медленно, однако механизм такого "резервирования" какой-то неуклюжий. Если Вы объясните великий смысл этого загадочного Number, нам будет много проще помочь


 
MsGuns ©   (2009-02-13 12:15) [10]

Пардон, не запрос, а хранимку или функцию (не знаком с лайтом)


 
Кщд   (2009-02-13 12:29) [11]

>Поиск "дырки" в записях
не ясно, какой смысл в этом поиске, если база данных - многопользовательская


 
Виталий Панасенко   (2009-02-13 12:51) [12]


> Кщд   (13.02.09 12:29) [11]

лайт, кажись, как раз однопользовательский


 
Кщд   (2009-02-13 13:02) [13]

>Виталий Панасенко   (13.02.09 12:51) [12]
как-будто многопользовательская...

http://www.sqlite.org/faq.html#q5
Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time, however.


 
Johnmen ©   (2009-02-13 13:03) [14]

Даже для однопользовательского проблема "дырок" - полная чушь...
:)


 
Maacheba   (2009-02-13 20:18) [15]

Чего-то не получается :(

Давайте на реальной базе уж, чтобы мозги не пудрить.
NUM_GLOBAL - как раз та переменная, в которой надо найти дырку.
Activity - признак активности. Если 0 - то значит запись считается "удаленной", если больше нуля - значит не удалена.

Сам пример базы:

http://pic.ipicture.ru/uploads/090213/6tnSNRtsIy.gif


> > where (MyTable.Number+1 > X) and ((m.Number is null) or
>
> > (m.FlagDeleting=0))
>
> вобщем сам разберешся, смысл, надеюсь понял..

не разобрался :(
Сделал такой запрос:

SELECT Clients.NUM_GLOBAL + 1 from Clients left join Clients c on (Clients.NUM_GLOBAL + 1 = c.NUM_GLOBAL) where  (Clients.NUM_GLOBAL+1 > 0) and ( (c.Activity=0) or (c.NUM_GLOBAL is null) )

Но он возвращает: 3 (вместо правильного ответа 1): http://pic.ipicture.ru/uploads/090213/X35ThyceyM.gif


> это условие помести в
>
> left join

сделал такой запрос:

SELECT Clients.NUM_GLOBAL + 1 from Clients left join Clients c on (Clients.NUM_GLOBAL + 1 = c.NUM_GLOBAL) and (c.Activity>0) where  (Clients.NUM_GLOBAL+1 > 0) and (c.NUM_GLOBAL is null)

Но он тоже возвращает: 3 - http://pic.ipicture.ru/uploads/090213/S5jJqY2BsO.gif

НИ-ЧЕ-ГО не понимаю (


 
Maacheba   (2009-02-14 12:40) [16]

Может SQLite чего-то не так делает...


 
sniknik ©   (2009-02-14 14:21) [17]

> Может SQLite чего-то не так делает...
конечно не то... ведь он делает то, что ему говорят(/пишут), а не то что при этом думают...

хотя не знаю что там с SQLite, но и для access логика запросов неверная (не говоря уже об идее поиска ничего не значащих "дырок")
вот так работает нормально (access!!!, но как видно логика изменена)
SELECT TOP 1 t1.NUM_GLOBAL + 1 AS [Дырка] FROM
Clients t1 LEFT JOIN Clients t2 ON (t1.NUM_GLOBAL + 1) = t2.NUM_GLOBAL AND t2.Activity = 0
WHERE t2.NUM_GLOBAL IS NULL


 
Maacheba   (2009-02-14 15:26) [18]

sniknik ©   (14.02.09 14:21) [17]

это аналог выражения, которое я выше написал:

SELECT Clients.NUM_GLOBAL + 1 from Clients left join Clients c on (Clients.NUM_GLOBAL + 1 = c.NUM_GLOBAL) and (c.Activity>0) where  (Clients.NUM_GLOBAL+1 > 0) and (c.NUM_GLOBAL is null)

только Activity>0 ты заменил на Activity = 0.

SQLite возвращает при этом запросе: 2
Хотя правильный ответ: 1

http://s52.radikal.ru/i137/0902/c9/ef9e9b991381.jpg
(зеркало): http://pic.ipicture.ru/uploads/090214/1x0B2LkXXj.gif


 
sniknik ©   (2009-02-14 17:20) [19]

> это аналог выражения, которое я выше написал:
ну пусть будет аналог.

> SQLite возвращает при этом запросе: 2
> Хотя правильный ответ: 1
а до того было, у "аналога"
> Но он тоже возвращает: 3 - http://pic.ipicture.ru/uploads/090213/S5jJqY2BsO.gif
на исходных данных
> Еще пример:
>
> Number | FlagDeleting
> ================
> 1         |  0
> 2         |  1
> 3         |  0
> 4         |  0
>
> Правильный ответ: 2
а теперь возвращает бывшее правильное 2... и опять не нравиться, теперь почему то правильным стала еденица. как понять тебя Саид?.


 
sniknik ©   (2009-02-14 17:41) [20]

и кстати, 1-у и не должно находить... она на первой записи и поэтому не может быть "дыркой", т.к. это начало отсчета. и с какой цифры бы оно не начиналось... в общем "дырки" это то что между, а начало с краю.
постаноу=вку задачи надо пересмотреть если тебе нужны не дырки а отсутствующие в каком то периоде/списке.


 
Maacheba   (2009-02-14 19:05) [21]

sniknik ©   (14.02.09 17:20) [19]
а до того было, у "аналога"


написано не просто "аналог", а "это аналог выражения... только Activity>0 ты заменил на Activity = 0"

sniknik ©   (14.02.09 17:20) [19]
а теперь возвращает бывшее правильное 2... и опять не нравиться


стоит заметить, что взяты разные примеры. В первом посте приведены данные от балды, чтобы показать СУТЬ задачи.

Само же тестирование делалось на реальной базе: http://pic.ipicture.ru/uploads/090213/6tnSNRtsIy.gif - и здесь правильный ответ: 1

sniknik ©   (14.02.09 17:41) [20]
постаноу=вку задачи надо пересмотреть если тебе нужны не дырки а отсутствующие в каком то периоде/списке


ну можно описать существующий смысл:

есть клиенты и у каждого клиента есть номер билета NUM_GLOBAL. Со временем клиенты могут удаляться физически (как запись из базы), а могут быть помечены как удаленные, при этом Activity выставляется в ноль. Для логики программы записи, где Activity стоит в 0 тоже самое, что этой записи вообще бы не было.

В таких условиях надо уметь искать НАИМЕНЬШИЙ доступный номер билета для выделения его новому клиенту. Нумерация билетов начинается с 1.

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


 
sniknik ©   (2009-02-14 19:42) [22]

> Само же тестирование делалось на реальной базе: http://pic.ipicture.ru/uploads/090213/6tnSNRtsIy.gif - и здесь правильный ответ: 1
вообще то, по описанию в [0], и здесь правильный ответ 2, или второй пример в [0] приводит неправильный ответ.

> P.S. Задача такова, как я ее описал.
да ну? а почему тогда при одинаковых исходных данных в разных постах у тебя верными считаются разные цифры?
и если вначале только СУТЬ, то почему из запроса не взята тоже только она и не подставлены сравнение на нужные значения? почему запрос взят as is?

> при этом Activity выставляется в ноль.
а в [0] во втором примере (на что я ориентировался) удаленной считается с FlagDeleting(Activity?) = 1

> В таких условиях надо уметь искать НАИМЕНЬШИЙ доступный номер билета для выделения его новому клиенту. Нумерация билетов начинается с 1.
ну так... введи точку отсчета - не стираемую запись со значением 0 и все, мой запрос будет работать... если ты конечно определишься наконец что у тебя считается удаленным а что нет, и поправишь под это, если конечно способен... а то ты видишь в выборке того что есть и присоединение к этому равнозначность выборке того что нет по одному способу игнорируя другой.

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


 
Johnmen ©   (2009-02-14 19:53) [23]


> Maacheba   (14.02.09 19:05) [21]

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

ЗЫ
Впрочем, если тебе завтра дадут задачу сделать велик с квадратными колесами, то ты можешь читать мантру "Задача такова, как я ее описал"
:))


 
Maacheba   (2009-02-14 21:33) [24]


> ну так... введи точку отсчета - не стираемую запись со значением
> 0 и все

без введения такой записи задачу средствами SQL решить невозможно?


> вообще то, по описанию в [0], и здесь правильный ответ 2,
>  или

блин... Я прошу прощения, что запутал, но в первом посте колонка FlagDeleting, она имеет противоположное значение реальной колонки Activity из реальной базы.

Реально запись считается удаленной, если Activity в 0. Если не ноль - то запись актуальна.

Давайте рассуждать о реальной базе теперь. Если нужно - я переделаю примеры:

NUM_GLOBAL | Activity
================
1                 |  [не ноль]
6                 |  [не ноль]
4                 |  [не ноль]
2                 |  [не ноль]

Правильный ответ: 3

Еще пример:

NUM_GLOBAL | Activity
================
1                 |  [не ноль]
2                 |  0
3                 |  [не ноль]
4                 |  [не ноль]

Правильный ответ: 2


 
Сергей М. ©   (2009-02-14 23:21) [25]


> Давайте рассуждать о реальной базе теперь


Ты ее сам лепил, базу эту ?
Или она досталась тебе в тяжелое наследство ?
Только честно уж, агрессивный ты наш) ..


 
Германн ©   (2009-02-15 00:55) [26]


> Только честно уж, агрессивный ты наш) ..

Против партизан почти нет приёмов. И это доказывают все исторические примеры, начинаю с середины прошлого века. А уж против агрессивных?
:)


 
Maacheba   (2009-02-15 13:17) [27]

Народ, задача остается пока, решение не придумал. Кратко сформулирую задачу:

есть клиенты и у каждого клиента есть номер билета NUM_GLOBAL. Со временем клиенты могут удаляться физически (как запись из базы), а могут быть помечены как удаленные, при этом Activity выставляется в ноль. Для логики программы записи, где Activity стоит в 0 тоже самое, что этой записи вообще бы не было.

В таких условиях надо уметь искать НАИМЕНЬШИЙ доступный номер билета для выделения его новому клиенту. Нумерация билетов начинается с 1.

Примеры:

NUM_GLOBAL | Activity
================
1                 |  [не ноль]
6                 |  [не ноль]
4                 |  [не ноль]
2                 |  [не ноль]

Правильный ответ: 3 (потому что это наименьшее число, начиная с 1, для которого запись отсутствует или activity равно нулю).

Еще пример:

NUM_GLOBAL | Activity
================
1                 |  [не ноль]
2                 |  0
3                 |  [не ноль]
4                 |  [не ноль]

Правильный ответ: 2 (потому что это наименьшее число, начиная с 1, для которого запись отсутствует или activity равно нулю).


 
Maacheba   (2009-02-15 18:30) [28]

Средствами SQL сделать это невозможно? ((
Время поджимает, поэтому сделаю так:

1) запрос на все данные и сортировка ORDER BY NUM_GLOBAL
2) вручную пробегаюсь от первой записи до последней, если следующая запись по NUM_GLOBAL отличается от предыдущей более, чем на единицу или если в следующей записи Activity=0, то значит нашел.

Правда, странно что это нельзя реализовать чисто в SQL, лишняя работа (


 
Maacheba   (2009-02-15 18:32) [29]

Удалено модератором
Примечание: Обсуждение модерирования


 
sniknik ©   (2009-02-15 19:20) [30]

> сходу решения никто не придумал.
да неужто прям бином Ньютона?... ;), чуток исправить то что я приводил (добавить поиск начала) и все будет под новые "правила"... пока ты их опять не поменял.  
правда это сработает (с исправлениями конечно), могу исправить,  для аксесс, mssql, vfp, даже под firebird который очень слабо знаю, и даже под нелюбимый оракл.... но вот для SQLite который в глаза не видел, и желания изучать нет... не обессудь.

> Сразу видно - вопрос для начинающих )
причем тут вопрос? ТЫ начинающий. т.к. ведешь себя соответственно.



Страницы: 1 вся ветка

Текущий архив: 2009.04.05;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.017 c
15-1234017094
oldman
2009-02-07 17:31
2009.04.05
Два вопроса от человека без интернета...


2-1234361101
JVtheGost
2009-02-11 17:05
2009.04.05
ODAC без клиента Oracle


10-1153589543
Andrey Kad.
2006-07-22 21:32
2009.04.05
Границы ячейки в Excel


15-1233558588
УбицоМух
2009-02-02 10:09
2009.04.05
Сообщение от сервера


15-1233816806
Slider007
2009-02-05 09:53
2009.04.05
С днем рождения ! 5 февраля 2009 четверг