Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Составление SQL-запросов > Пользователи кто в онлайн, кто не в онлайн rand()


Автор: numerovan 9.6.2014, 22:30
Здравствуйте, хочиться решить составление запроса.
Вопрос таков: есть пользователи сайта, есть блок где выводятся 12 случайных пользователей, хочиться сделать так чтоб вначале выходились те кто в онлайн (если таковы имеются), а остальные из 12 - случайные пользователи портала.
Как я вижу себе sql-запрос, сразу хочу сказать что он с ошибками, но смысл хочу показать запроса:
Код

SELECT id, name, last_act FROM users WHERE id IN (
      (SELECT id FROM users WHERE last_act > (NOW()-300) ORDER BY last_act DESC LIMIT 12)
      UNION
     ( SELECT id FROM users WHERE last_act < (NOW()-300) ORDER BY RAND() LIMIT 12)
) LIMIT 12


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

Есть какие нибудь предположения ?

Автор: Akina 10.6.2014, 07:45
Цитата(numerovan @  9.6.2014,  23:30 Найти цитируемый пост)
чтоб вначале выходились те кто в онлайн (если таковы имеются), а остальные из 12 - случайные пользователи портала

Приведённый запрос эту часть задачи не решает.

Цитата(numerovan @  9.6.2014,  23:30 Найти цитируемый пост)
думаю это плохо по производительности 

Докажите. Выражения типа "мне кажется" доказательством не являются.

Цитата(numerovan @  9.6.2014,  23:30 Найти цитируемый пост)
было бы лучше сократить 

Преждевременная оптимизация - всегда плохо.

Автор: numerovan 10.6.2014, 10:50
может я плохо выразился и код, что написал, не соответствует ....
Смысл таков:

если есть пользователи онлайн, то вначале показывать их, если пользователей онлайн меньше 12, например их 5, то остальные 7 пользователей добавлять путем  rand-омайза (выборочные случайные пользователи).

На данный момент я решил эту задачу путем трех обращений к базе данных, т.е. делаются 3 запроса:
1. выбрать пользователей кто в онлайн, не больше 12
2. если пользователей меньше 12, получить остаток случ. пользователей рандомайзом.
3. соединить результат.

хочиться одним запросом, убить двух зайцев ...

Автор: Akina 10.6.2014, 11:11
Код

SELECT id, name, last_act 
FROM users
ORDER BY last_act > (NOW()-300), RAND()
LIMIT 12

Автор: numerovan 11.6.2014, 08:07
проверил ваш код, признаюсь не работает он ... всмысле в начале списка не выходят пользователи кто в онлайн, а рандомайз да работает.

Есть еще варинаты ?

Автор: Akina 11.6.2014, 09:17
Конечно, есть. Только они для тебя очень уж обидные...

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

Автор: numerovan 11.6.2014, 09:59
не спорю, знаю что я не силен в sql-запросах, основы знаю ... но вот если попадются не простые ситуации, то тут начинаю тормозить. Вы стого не судите меня, ведь этот форум и расчитан на обмен знаниями и моя ситуация это нормальная. Написали бы стразу что там намерено чуток не правильно написали, мол типо "а остальное додумайся сам" - без проблем ... зачем так умничать не понимаю ... но все равно спасибо.

Автор: numerovan 11.6.2014, 10:21
вот так вроде заработало
Код

SELECT id, name, last_act 
FROM users
ORDER BY last_act > (NOW()-300) DESC, RAND()
LIMIT 12

Автор: Akina 11.6.2014, 11:05
Ну вот, всегда бы так... хотя проще было просто поменять знак в условии сравнения в секции сортировки.
Цитата(numerovan @  11.6.2014,  10:59 Найти цитируемый пост)
если попадются не простые ситуации, то тут начинаю тормозить.

Если ты понял ПРИЁМ, который тут использован - он больше никогда у тебя трудностей не вызовет. И вопросов таких соответственно просто не будет. 

Автор: numerovan 11.6.2014, 18:46
вот так хорошо да ...
Код

SELECT id, name, last_act 
FROM users
ORDER BY last_act < (NOW()-300), RAND()
LIMIT 12

Автор: numerovan 12.6.2014, 16:21
----

Автор: numerovan 13.6.2014, 01:42
---

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)