Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: рандомная выборка и JOIN
Покинул форум
Сообщений всего: 354
Дата рег-ции: Янв. 2011 Откуда: Пружаны Бресткая обл. Беларусь
Помог: 2 раз(а)
здравствуйте
если кто не отдыхает подскажите пожалуйста как реализовать, чтоб быстро и правильно:
есть (кратко)
т1 где ид, название тема
т2 где ид, номер темы, адрес картинки
тоесть в т2 много строк соответствующих разным темам из т1
при загрузке страницы выводятся названия тем из т1 и картинки, соответствующие темам из т2
требуется сделать так, чтобы при загрузке страницы картинки к темам из т1 были каждый раз рандомно выбранными/разными, выбранными из т2
я запутался уже..
куда и как RAND() подставить ? или как реализовать?
(рандомная выборка и JOIN ненагуглил)
подскажите пожалуйста
EuGen
Отправлено: 05 Января, 2013 - 17:32:49
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
JOIN сопоставит все строки из t2 строкам из t1, соответственно максимум, что Вы получите - перемешивание результирующих строк. Это достигается при помощи ORDER BY RAND()
Либо же Вам нужно выбирать не все строки из t2, а лишь некоторое количество? (Например, есть 10 фото для некоторой темы, из которой нужно отображать 3 случайных) - тогда задача решается иным способом.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
broshurkaplus
Отправлено: 05 Января, 2013 - 17:45:58
Посетитель
Покинул форум
Сообщений всего: 354
Дата рег-ции: Янв. 2011 Откуда: Пружаны Бресткая обл. Беларусь
Помог: 2 раз(а)
так и есть мне нужно выбирать случайную картинку, одну из многих возможных, для каждой из тем в т1., темы выводятся все всегда, а картинки нужно выбирать случайно к этим темам.
+ в т2 будет более 100к записей
т.е. я запрашиваю список тем - а к ним (к каждой теме 1 картинка) из т2 рандомно выбирается соответствующая теме картинка.
(я уже думаю может делать рандом по т2, к ней join т1, группировать и сортировать по названию темы)
подскажите пожалуйста 2вариант, и если можно пример, я протесчу. спасибо
сегодня походу отдыхаем...
так сформудирую: есть 10 тем по 20 фото для каждой, нужно вывести все 10 тем и для каждой отобразить случайную соответствующую теме 1 из 20 возможных картинок.
(SELECT photo FROM t2 WHERE t1_id=main_id ORDERBY RAND()LIMIT 1)AS t1_photo
FROM t1;
- однако explain такого запроса с DEPENDED SUBQUERY, несомненно, Вас огорчит. Потому я бы рекомендовал найти случайные значения id фотографии через php-скрипт. Это потребует большего количества памяти, но быстродействие повысится.
Находить случайный id можно, например, в несколько шагов. Первым шагом вычислить количество фото для каждой темы (элементарный SQL, COUNT + GROUP BY); вторым - сгенерировать массив из случайных значений от 1 до соответственно каждого найденного из значений (это, по сути, будет массив смещений), а затем уже выбирать фото при помощи LIMIT. Способ подойдет, когда выбираемых тем будет не слишком много (дабы запросов на LIMIT тоже не было чрезмерно много).
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
broshurkaplus
Отправлено: 05 Января, 2013 - 21:01:16
Посетитель
Покинул форум
Сообщений всего: 354
Дата рег-ции: Янв. 2011 Откуда: Пружаны Бресткая обл. Беларусь
Помог: 2 раз(а)
я пробовал пока по разному, пришел к следующим выводам:
дело в том, что реально организованно так
тем порядка 70
в каждой теме есть/будет около 30 подтем...
и картинок всего ожидается не менее 100к следовательно и строк в таблице бд, ведь не делать же каждой теме таблицу
сортировка по ORDER BY RAND() при такой вложенности будет "не быстрой" походу. пока я сделал подсчет картинок при добавлении их, те добавляем- увеличиваем на 1 значение в таблице тем и подтем - получается я сразу имею количество ид картинок для каждой из тем и подтем и могу рандомно выбрать номер.
напр. в теме цветы -5360 картинок выбираю ранд от 1 до 5360
т.о. буду выбирать для каждой темы сначала ранд из общего количества
а потом в цикле выводить нужную картинку.
я думаю так будет быстрее, нужно всего лишь сделать ранд для каждой темы и реально юзер не будет 100 раз за сессию смотреть полный список тем, поэтому можно, чтобы быстрее было ограничиться не 5360 а 100 (с 1 по 100), ну и следующий раз сменить скриптом... с 125 по 225
как вы оцениваете такой момент? мешать не в бд а просто цифры, а потом брать из бд нужную?
(LIMIT я всегда использую, когда знаю требуемое кол-во, писали, что это скорость добавляет)
единственное, что может быть, если часть картинок будет удалена, как мне в "дыру" по ид не попасть? проверять есть ли результат и тупо в цикле добавлять значение+1 пока не вернет нужное или есть какой-то (нехитроумный) способ?
еще подумал, что если имеем 5360, то точнее это не ид будет а количество записей для соотв-й темы, следовательно можно обратиться к рандомно выбранному номеру записи в выборке для соотв-й темы, например запись/строка 856...
но как непосредственно к номеру строки в запросе обратиться? получить данные из заданной строки?.. что то не пойму... ведь мы все всегда лепим ид да условия..
если не трудно, оцените такой вариант, и как к строке обратиться, или еще какие предложения/идеи есть?
а пока, чтоб не стоять на месте, я просто вывожу по группировке, получается всегда 1я картинка, но заказчик упорно требует случайную! ( не лучшую по рейтингу или комментариям )
жду... чего нибудь. спасибо.
tuareg
Отправлено: 05 Января, 2013 - 23:18:15
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Можно сделать так. Вам ведь нужна случайная картинка? Вводите доп. поле, в которое пишите порядковый номер картинки. 1,2, N. По нему индекс, лучше даже индекс типа группа+это поле, можно сделать его уникальным.
Теперь запросы на выборку.
# я пишу *, но лучше перечислите те поля, которые Вам реально надо
SELECT*FROM`table`WHERE`parent`=1 AND increment IN('тут массив через запятую');
Это что касается вывода.
Необходимо еще поддерживать целостность поля increment.
При вставке просто увеличивайте на +1
При удалении:
Перед удалением выполните сначала найдите increment удаляемой записи
UPDATE`table`SET`increment`=`increment`удаляемой записи WHERE`parent`=`parent`AND`increment`=MAX(`increment`)
Последний запрос скорей всего некорректен (синтаксис не правилен на счет MAX(increment)), но общая логика понятна. EXPLAIN этих запросов будет достаточно хорош
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.