За последние 24 часа нас посетили 22870 программистов и 1232 робота. Сейчас ищут 752 программиста ...

Вывести из базы 1 строку с шансом

Тема в разделе "PHP и базы данных", создана пользователем #Ivan, 30 ноя 2019.

  1. qdevelopment

    qdevelopment Новичок

    С нами с:
    13 окт 2019
    Сообщения:
    41
    Симпатии:
    13
    Автор, если нужна 100% гарантия, ни один алгоритм получения случайного числа вам не поможет. Если у вас 1000 лотерейных билетов, а у меня 1, вероятность вашего выигрыша огромна, но не 100%-на.

    Создайте в таблице поле qty, каждому подарку вбейте в это поле столько, сколько в реале вы будете отправлять. При поиске подарка, сортируйте по этому полю по убыванию, и строке которую получили уменьшайте qty на 1.

    Или храните в отдельной таблице всю последовательность подарков.
     
    #26 qdevelopment, 30 ноя 2019
    Последнее редактирование: 30 ноя 2019
    #Ivan нравится это.
  2. #Ivan

    #Ivan Новичок

    С нами с:
    7 ноя 2019
    Сообщения:
    28
    Симпатии:
    1
    вбейте в это поле столько, сколько в реале вы будете отправлять. В смысле сколько будете отправлять?
     
  3. qdevelopment

    qdevelopment Новичок

    С нами с:
    13 окт 2019
    Сообщения:
    41
    Симпатии:
    13
    Ну например подарок с шансом 90%, туда пишете 5000 штук, подарку с шансом 10% 50 штук. Далее при поиске, сортируйте по этому полю по убыванию, когда нашли, этому подарку уменьшайте это поле на 1.

    Или же как я дописал в том сообщении, храните в отдельной таблице всю последовательность подарков.
     
    #28 qdevelopment, 30 ноя 2019
    Последнее редактирование: 30 ноя 2019
    #Ivan нравится это.
  4. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    Это первое, что я предложил и это единственный вариант учёта реальных процентов шанса, но нужен ещё и период времени, за который сбудутся все хотелки ТС. Но увы и ах, ТС хочет гарантий, но упорно делает рандом.
     
    #Ivan нравится это.
  5. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.794
    Симпатии:
    650
    Если каких-то призов, например дорогих, ограниченное кол-во, то при их выигрыше их исключают из розыгрыша (можно втихую, до оглашения окончательных результатов, чтобы раньше времени не снижать интерес к розыгрышу).

    Что касается вероятностей (шансов), в чем проблема снабдить каждый вид приза коэффициентом вероятности? Пример практической реализации вам уже подсказали. Генерируете «поверх» осн. таблицы доп. таблицу, в кот. кол-во записей для каждого вида приза пропорционально вероятности его выпадения. Можете, в качестве значения вероятности использовать, например, не долю единицы/проценты, а просто целое число, определяющее кол-во записей в доп. таблице для данного вида приза. Есть и др. способы.
    --- Добавлено ---
    Что это за условие/поле?
    Код (Text):
    1. `caseid`='{$id}'
     
    #Ivan нравится это.
  6. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    Я не читал подробно что советуют. Но мне кажется казино работают так - прибыль должна быть больше расхода. Например у тебя 1000 у.е. Из них на подарки ты можешь потратить 40% от суммы прибыли. На старте у тебя прибыль 0. То есть изначально по логике ты в минусе. То есть ты можешь раздавать только самые дешевый подарки. Итак распределим иерархию подарков.

    1. Подарки от 800 до 1000 у.е
    2. Подарки от 600 до 800 у.е
    3. Подарки от 400 до 600 у.е
    4. Подарки от 200 до 400 у.е
    5. Подарки от 100 до 200 у.е
    6. Подарки от 10 до 100 у.е
    7. Подарки от 2 до 9 у.е
    8. Подарки от 1 до 2 у.е

    Самые дешевый у нас будут считаться 7,8. То есть ты не имеешь права дарить подарки выше.
    Допустим в течении часа от начала у тебя прибыль 2000 у.е
    2000 - 40% = 800 у.е
    Теперь ты можешь уже дарить рандомно все подарки кроме 1 пункта.
    Но как только ты даришь подарок он вычитается и твоей прибыли.
    Вот и весь рандом.
    прибыль - 40% = максимальная возможность цены подарка.

    Все просто как три копейки. Смотря какая твоя жадность ты просто настраиваешь процент и все.
     
    #Ivan нравится это.
  7. #Ivan

    #Ivan Новичок

    С нами с:
    7 ноя 2019
    Сообщения:
    28
    Симпатии:
    1
    номер "коробки" призов то 11 тысяч но из них не все принадлежат одной коробки
     
  8. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.794
    Симпатии:
    650
    P.S. Записи в доп. таблице можно дополнительно не перемешивать. Они могут лежать «отрезками», соответствующими записям осн. таблицы.
    --- Добавлено ---
    ??? Это ответ на мой вопрос?
    --- Добавлено ---
    Чтобы выдрать в цитату фрагмент поста, выделите его и щелкните «Ответить» в появившейся всплывающей подсказке.
     
    #Ivan нравится это.
  9. #Ivan

    #Ivan Новичок

    С нами с:
    7 ноя 2019
    Сообщения:
    28
    Симпатии:
    1
    Да
    --- Добавлено ---
    Ну давайте коробку назовем категорией где можно выиграть определенный приз. У меня одна таблица для всех призов категорий.
     
  10. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.794
    Симпатии:
    650
    Разные розыгрыши что ли? Т.е. прямого отношения к вопросу это условие не имеет.
     
    #Ivan нравится это.
  11. #Ivan

    #Ivan Новичок

    С нами с:
    7 ноя 2019
    Сообщения:
    28
    Симпатии:
    1
    Да. Я наверно всех запутал? глупо получилось.
     
  12. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    По таблице это будет так
    Таблица прибыли:

    Код (Text):
    1. цена | тип_цены
    2. 10   | 1
    3. 8    | 0
    4. 11   | 1
    5. 20   | 1
    6. 1    | 1
    7. 100  | 1
    8. 20   | 0
    0/1 - расход/прибыль

    Таблицы подарков
    Код (Text):
    1. id_подарка | название | цена
    2. 1          | машина   |  2000
    3. 2          | ручка    | 1
    4. 3          | пиво     | 10
    B обычным sql запросом считаешь сумму прибыли - 40% = 1 случайный подарок не больше расчетной цены.
     
    #37 Artur_hopf, 30 ноя 2019
    Последнее редактирование: 30 ноя 2019
    #Ivan нравится это.
  13. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    почитай, а заодно и ТЗ почитай
     
    #Ivan нравится это.
  14. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    Мне кажется топикстартер напрасно считает задачу сложной.
    Вполне естественно хранить все призы в таблице. Пусть там будет 10 дорогих, 100 средних и 500 дешёвых, это абсолютно не влияет на алгоритм. Там просто все призы. Хранить все экземпляры, а не типы призов.

    При выигрыше надо выбранный приз удалять или помечать как недоступный. Итого мы всегда имеем таблицу с доступными в данный момент призами. Вероятность поддерживается натуральным образом без специальных уловок: чем меньше осталось каких-то записей, тем меньше шансов, что будет выбрана именно такая запись. И абсолютно натуральным образом не получится выдать призов больше чем задумано изначально. Потому что они тупо кончатся и нечего будет выбирать!

    Остаётся решить как выбирать "случайную" запись. ORDER BY RAND() дорогая операция, но это не имеет значения если в таблице всего пяток строк. Временная перемешанная таблица поместится в кеше, в оперативной памяти сервера. Вот на больших таблицах уже надо трюкачить. Ещё раз: если у тебя число записей двух или трехзначное, то считай ты уже решил задачу, дальше не читай.

    - - -

    Трюк 1 с выборкой из большой таблицы тоже не rocket science :) У тебя есть первичный ключ, скорее всего автоинкремент. Один раз найди значение MAX(id). Вычисли на стороне PHP случайный "номер записи", $n = mt_rand(1, $maxId). Так как в нашей таблице будут "дырки", то запрос надо делать не на точное попадание, а на первую запись с ... WHERE id >= :n. Если вдруг нет такой записи (уже весь хвост выбрали), то повторить рандом и выборку. И так до момента пока не найдёшь подходящую запись или таблица не станет пустой.

    Трюк 2 с однократным перемешиванием тоже прост. Заполни таблицу в циклах 10 дорогих, 100 средних и 500 дешёвых или как там тебе надо, а потом сделай копию таблицы через
    INSERT INTO table2 ( SELECT * FROM table1 ORDER BY RAND() )
    В запросе нет LIMIT и его надо выполнить только один раз!
    Выбирай из второй таблицы всегда первую доступную запись (с минимальным id) и удаляй / отмечай запись как недоступную. И так пока доступные записи не закончатся.
     
    #39 artoodetoo, 1 дек 2019
    Последнее редактирование: 1 дек 2019