Как реализовать случайный вывод из БД, с учетом рейтинга данных.

Статус
В этой теме нельзя размещать новые ответы.
select c1
from t1
where rating>FLOOR(SQRT(rand())*(5-1))
order by rating
limit 1

Добавлено через 23 минуты
похоже работать не будет :ah:,
т.е. если несколько записей с рейтингом 5 , то будет выдаваться всегда одна.
Не знаю. :nezn: Может попытаться растянуть диапазон чтоб было 1- 500000.
И те записи которые имеют рейтингом 5, были бы разбросаны.
Тогда бы работало...

Добавлено через 47 минут
Но если записей не много, и сервер не помрет - попробуй:
order by POW(rating,2)*rand() DESC
или
order by POW(rating,3)*rand() DESC
и т.д.
 
Попробую еще ;)
Делаем дополнительное поле
rating2 = POW(rating+rand(),2)

нужно определить rating2_max , rating2_min

И выборка будет примерно такая
where rating2>(rand()*(rating2_max-rating2_min) + rating2_min)
order by rating2
limit 1 :yahoo:
 
Ты смайлами хоть обвешайся, только задачу ТС одним мускулем не решить (если не использовать встроенные тригеры и функции).
 
я бы делал так: у каждой записи свой вес(ну или рейтинг). в скрипте задаем диапазон весов (от и до) и частотность выборки записей в пределах каждого диапазона. примерный алгоритм:

1. для диапазона с рейтингом от 5000 до 10000 задано 10 выборок (показов)
2. для диапазона с рейтингом от 1000 до 5000 задано 5 выборок (показов)
3. для диапазона с рейтингом от 0 до 1000 задано 2 выборки (показа)
4. делаем выборку записей с рейтингом 1. рандомно выводим одну. повторяем 10 раз.
5. делаем выборку записей с рейтингом 2. рандомно выводим одну. повторяем 5 раз.
6. делаем выборку записей с рейтингом 3. рандомно выводим одну. повторяем 2 раза.
7. переходим на шаг 4 и по новой...

алгоритм сырой - в 3 часа ночи плохо думается. ((
 
в баннерных сетях инфа грузится в память, вся, а уже там, средствами С++ (РНР?) происходит выборка, и обновление инфы по расписанию
такая выборка средствами MySQL однозначно будет грузить сервак
 
такая выборка средствами MySQL однозначно будет грузить сервак
Хватит переливать из пустого в порожнее - такая выборка средствами MySQL (стандартный sql-запрос) невозможна.
Можно заморочится с хранимыми процедурами, но оно того не стоит.
 
Можно сохранять сколько раз была показана поговорка, тогда проверять поля рейтинга и показа, сначала берётся случайная поговорка:
Код:
SELECT * FROM pogovorki WHERE show_time<rating ORDER BY rand() LIMIT 1;
Дальше обновляется показ всех поговорок с таким рейтингом:
Код:
UPDATE pogovorki SET show_time = show_time + 1 WHERE rating = какой-то;
А если случайной поговорки нет, тогда обнуляем показ всех поговорок:
Код:
 UPDATE pogovorki SET show_time = 0
Или ещё можно связать со временем, например в течении 5 секунд поговорку с рейтингом 5 можно брать каждую секунду, с рейтингом 4 каждые 1,25 с, 3 каждые 1,667 с и т. д.
Код:
SELECT
TIME_FORMAT(NOW(),'%s') time_sec,
5/rating show_every_x_sec,
((TIME_FORMAT(NOW(),'%s')%5)+1)%(5/rating) show_rating,
rating,
pogovorki.* 
FROM pogovorki
WHERE ROUND(((TIME_FORMAT(NOW(),'%s')%5)+1)%(5/rating)) = 0
ORDER BY rand()
LIMIT 1;
Или сортировать по случайной вероятности с весом рейтинга:
Код:
SELECT * FROM pogovorki ORDER BY RAND() / rating * RAND() LIMIT 1
Для php тут есть подробно:

PHP:
function w_rand($weights) {
    $r = mt_rand(1,1000);
    $offset = 0;
    foreach ($weights as $k => $w) {
        $offset += $w*1000;
        if ($r <= $offset) {
            return $k;
        }
    }
}
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху