Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.03.2014, 23:35   #1
unbanned
Форумчанин
 
Аватар для unbanned
 
Регистрация: 23.11.2010
Сообщений: 530
По умолчанию вывод рандомной записи

Подскажите как правильно решить такого рода задачу...
Есть много строк нужно вывести рандомно одну из всех, но такую, которая не выводилась при предыдущих запусках программы.

первое что пришло в голову записать их в текстовый файл.

при запуске читать файл в переменную.

посчитать количество строк в переменной.
вывести строку c номером i:=random(n)+1
удалить строку с номером i
посчитать количество строк в переменной.
...
вывести
удалить
посчитать
...
при выходе из программы переписать файл.

но это хорошо, когда строк не много... и весь файл можно прочитать в переменную.

а если строк будет много?
как быть тогда?
unbanned вне форума Ответить с цитированием
Старый 03.03.2014, 05:03   #2
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Если строка будет считываться 100% единажды и не более, то я б сделал в БД ещё одно поле was_read логического типа. Как прочел, ставишь галку.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 03.03.2014, 13:04   #3
unbanned
Форумчанин
 
Аватар для unbanned
 
Регистрация: 23.11.2010
Сообщений: 530
По умолчанию

я думал о чем то подобном, но...

допустим рандомить ID и проверять поле was_read
тогда нужно повторять в цикле вывод пока не совпадет условие т.е. чем меньше останется записей тем больше будет интераций цикла...
unbanned вне форума Ответить с цитированием
Старый 03.03.2014, 13:17   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
тогда нужно повторять в цикле вывод пока не совпадет условие т.е. чем меньше останется записей тем больше будет интераций цикла...
или брать ближайшую из возможных (не выбранных раннее)

Код:
select max(id) from t where id<randID and was_read=false
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 03.03.2014, 13:26   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

А когда все строки исчерпаются - прога не запускается?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 03.03.2014, 13:49   #6
unbanned
Форумчанин
 
Аватар для unbanned
 
Регистрация: 23.11.2010
Сообщений: 530
По умолчанию

спасибо за идею.

а если случится такая ситуация, что не выводившиеся ранее записи останутся только с ID большим чем randID?

допустим 300 записей, а randID=250... а не выводились последние 50.


P.S.

Цитата:
А когда все строки исчерпаются - прога не запускается?
я думаю это не принципиально. можно запустить и вывести сообщение... или это важно для алгоритма?

Последний раз редактировалось unbanned; 03.03.2014 в 13:53.
unbanned вне форума Ответить с цитированием
Старый 03.03.2014, 14:29   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
а если случится такая ситуация, что не выводившиеся ранее записи останутся только с ID большим чем randID?
допустим 300 записей, а randID=250... а не выводились последние 50.
Ну, тогда повторять в цикле для нового случайного randID, пока не вернётся нужное значение.


Цитата:
я думаю это не принципиально. можно запустить и вывести сообщение... или это важно для алгоритма?
важно в том смысле, чтобы не получить БЕСКОНЕЧНЫЙ цикл.

я бы предложил такую схему:
при запуске
Код:
 select count(*) as cntNoRead from t where was_read=false
если cntNoRead = 0 - сообщение, что больше нет подходящих записей и выход!

если cntNoRead = 1 то
Код:
select id from t where was_read=false
иначе:
тот самый цикл выбора значений (можно кодом, предложенным выше, а можно, я бы лично сделал именно так, вытащить все невыпавшием номера и выбрать номер среди них)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 04.03.2014, 14:40   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
а если случится такая ситуация, что не выводившиеся ранее записи останутся только с ID большим чем randID?
подумать и расширить приведенный код
Цитата:
99% кода в интернете никуда не годно.
в том числе и приведенный мною для иллюстрации идеи
Код:
select top 1 
from (select max(id) from t where id<randID
 union select min(id) from t where id>randID )
P.S. если подумать можно обойтись и без max/min

Код:
select top 1 id from t where id >randID order by id desc
P.P.S. код опять неполный, чтобы можно было подумать
а если ...
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 04.03.2014 в 14:44.
evg_m вне форума Ответить с цитированием
Старый 05.03.2014, 00:59   #9
unbanned
Форумчанин
 
Аватар для unbanned
 
Регистрация: 23.11.2010
Сообщений: 530
По умолчанию

я понял спасибо всем за советы. буду пробовать...
unbanned вне форума Ответить с цитированием
Старый 05.03.2014, 09:17   #10
IliaIT
Форумчанин
 
Аватар для IliaIT
 
Регистрация: 17.03.2009
Сообщений: 977
По умолчанию

можно продумать метод для базы. делаем глобальный селект всех записей. в каждой записи есть поле проверки выбора. рандом указывает на строку и вы выставляете в базе 1 в поле вывода. далее настраиваем фильтр бдгрида что бы не отображать строки с проверкой равной 1. (или эту единичку записать в базу и заново селект но уже с ограничением что с единичками не берём строки). и так далее пока не останется пустой набор.
Интуитивно понятный интерфейс - это такой интерфейс, для работы с которым нужна недюжинная интуиция.
IliaIT вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Записи!RadioGroup вывод варианта wlll Общие вопросы Delphi 3 21.04.2013 17:01
Рандомное значение в рандомной кнопке konserva Общие вопросы Delphi 2 11.04.2012 16:06
Вывод последней записи из таблицы mysql NapalmRain PHP 4 24.06.2011 14:41
Вывод поля записи ofenod Паскаль, Turbo Pascal, PascalABC.NET 3 30.03.2011 18:27
вывод записи поиска artemi Общие вопросы C/C++ 3 24.05.2010 22:01