Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.04.05;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.006 c
2-1234787510
abhtr
2009-02-16 15:31
2009.04.05
Смена кодировки Win -> DOS для string


15-1233787788
Германн
2009-02-05 01:49
2009.04.05
Телефон, телефонный кабель и RJ разъём


15-1233869486
Юрий
2009-02-06 00:31
2009.04.05
С днем рождения ! 6 февраля 2009 пятница


4-1207825025
Виталий
2008-04-10 14:57
2009.04.05
Узнать хендлы открытых процессом файлов


2-1234501240
dark_volk
2009-02-13 08:00
2009.04.05
Копирование таблиц





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский