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

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: выбрать случайные данные из т2 и присоединить к т1
broshurkaplus
Отправлено: 05 Января, 2013 - 17:29:27
Post Id



Посетитель


Покинул форум
Сообщений всего: 354
Дата рег-ции: Янв. 2011  
Откуда: Пружаны Бресткая обл. Беларусь


Помог: 2 раз(а)




здравствуйте
если кто не отдыхает подскажите пожалуйста как реализовать, чтоб быстро и правильно:
есть (кратко)
т1 где ид, название тема
т2 где ид, номер темы, адрес картинки
тоесть в т2 много строк соответствующих разным темам из т1

при загрузке страницы выводятся названия тем из т1 и картинки, соответствующие темам из т2

требуется сделать так, чтобы при загрузке страницы картинки к темам из т1 были каждый раз рандомно выбранными/разными, выбранными из т2
я запутался уже..

вот код
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM `темы`
  2.   LEFT JOIN `картинки`
  3.     ON темы.id=картинки.num_темы
  4.     GROUP BY темы.id
  5.     ORDER BY `темы.название`


куда и как RAND() подставить ? или как реализовать?
(рандомная выборка и JOIN ненагуглил)

подскажите пожалуйста
 
 Top
EuGen Администратор
Отправлено: 05 Января, 2013 - 17:32:49
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




JOIN сопоставит все строки из t2 строкам из t1, соответственно максимум, что Вы получите - перемешивание результирующих строк. Это достигается при помощи ORDER BY RAND()
Либо же Вам нужно выбирать не все строки из t2, а лишь некоторое количество? (Например, есть 10 фото для некоторой темы, из которой нужно отображать 3 случайных) - тогда задача решается иным способом.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
broshurkaplus
Отправлено: 05 Января, 2013 - 17:45:58
Post Id



Посетитель


Покинул форум
Сообщений всего: 354
Дата рег-ции: Янв. 2011  
Откуда: Пружаны Бресткая обл. Беларусь


Помог: 2 раз(а)




так и есть мне нужно выбирать случайную картинку, одну из многих возможных, для каждой из тем в т1., темы выводятся все всегда, а картинки нужно выбирать случайно к этим темам.

+ в т2 будет более 100к записей
т.е. я запрашиваю список тем - а к ним (к каждой теме 1 картинка) из т2 рандомно выбирается соответствующая теме картинка.

(я уже думаю может делать рандом по т2, к ней join т1, группировать и сортировать по названию темы)
подскажите пожалуйста 2вариант, и если можно пример, я протесчу. спасибо

сегодня походу отдыхаем...
так сформудирую: есть 10 тем по 20 фото для каждой, нужно вывести все 10 тем и для каждой отобразить случайную соответствующую теме 1 из 20 возможных картинок.

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

(Отредактировано автором: 05 Января, 2013 - 18:26:05)

 
 Top
EuGen Администратор
Отправлено: 05 Января, 2013 - 19:38:31
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Задача, по сути, сводится к нахождению случайной строки (либо M случайных строк) N раз, где N - число строк в t1.
Через SQL можно сделать так:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT t1.id AS main_id, t1.name,
  2. (SELECT photo FROM t2 WHERE t1_id=main_id ORDER BY RAND() LIMIT 1) AS t1_photo
  3. FROM t1;

- однако explain такого запроса с DEPENDED SUBQUERY, несомненно, Вас огорчит. Потому я бы рекомендовал найти случайные значения id фотографии через php-скрипт. Это потребует большего количества памяти, но быстродействие повысится.
Находить случайный id можно, например, в несколько шагов. Первым шагом вычислить количество фото для каждой темы (элементарный SQL, COUNT + GROUP BY); вторым - сгенерировать массив из случайных значений от 1 до соответственно каждого найденного из значений (это, по сути, будет массив смещений), а затем уже выбирать фото при помощи LIMIT. Способ подойдет, когда выбираемых тем будет не слишком много (дабы запросов на LIMIT тоже не было чрезмерно много).


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
broshurkaplus
Отправлено: 05 Января, 2013 - 21:01:16
Post Id



Посетитель


Покинул форум
Сообщений всего: 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я картинка, но заказчик упорно требует случайную! ( не лучшую по рейтингу или комментариям )

жду... чего нибудь. спасибо.
 
 Top
tuareg
Отправлено: 05 Января, 2013 - 23:18:15
Post Id


Участник


Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010  


Помог: 69 раз(а)




Можно сделать так. Вам ведь нужна случайная картинка? Вводите доп. поле, в которое пишите порядковый номер картинки. 1,2, N. По нему индекс, лучше даже индекс типа группа+это поле, можно сделать его уникальным.
Теперь запросы на выборку.
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. #increment это как раз то поле
  3. #parent это связь :)
  4. SELECT MAX(`increment`)  FROM `table` WHERE `parent`=1;
  5.  

Получим сколько всего картинок. Дальше я думаю и так все ясно. Сгенерировали массив случайных от 0 до MAX(`increment`) И запрос
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. # я пишу *, но лучше перечислите те поля, которые Вам реально надо
  3. SELECT *  FROM `table` WHERE `parent`=1 AND increment IN('тут массив через запятую');
  4.  

Это что касается вывода.
Необходимо еще поддерживать целостность поля increment.
При вставке просто увеличивайте на +1
При удалении:
Перед удалением выполните сначала найдите increment удаляемой записи
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT `increment`,`parent` FROM `table` WHERE `id`=1;
  3. UPDATE `table` SET `increment`=`increment`удаляемой записи WHERE `parent`=`parent` AND `increment`=MAX(`increment`)
  4.  

Последний запрос скорей всего некорректен (синтаксис не правилен на счет MAX(increment)), но общая логика понятна. EXPLAIN этих запросов будет достаточно хорош Улыбка

(Отредактировано автором: 06 Января, 2013 - 01:44:41)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB