[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Отнести фильм к нескольким категориям
Krevedko
Добрый день всем. Хочу реализовать функционал как например на DLE (да и на других цмс наверное также).
Пусть имеется таблица с фильмами. И имеется таблица с жанрами. Естественно фильм одновременно может быть скажем Комедия и Мелодрама. Или Фантастика, Приключения и Боевик, т.е. относиться к нескольким жанрам. Итого связь многие ко многим. Я создал отдельно таблицу с полями category_id и film_id. И соответственно пишу скажем 1 и 1, 1 и 2, 2 и 1. Т.е. Фильм с ид 1 относится к жанру с ид 1, ид 2 тоже к жанру 1 и наконец опять же фильм с ид1 -относится еще и жанру 2. Для выборки использую JOIN, все выбирает, но вот тут и подкралась засада. При объединении получается, что выводится таблица типа:
Боевик - Первый мститель
Боевик - Ключ Саламандры
Фантастика - Первый мститель.
И если выводить это все в хтмл, то выводится ессно Два одинаковых фильма, но как бы разных жанров. А мне надо как в дле, чтобы выводился один фильм, но в графе Жанры стояло Боевик, Фантастика (думаю все видели как это выглядит).
Что-то сижу, думаю второй час и никак не могу придумать как правильно это реализовать.



Спустя 7 минут, 5 секунд (19.09.2011 - 18:41) vital написал(а):
Цитата
Пусть имеется таблица с фильмами.

Цитата
И имеется таблица с жанрами

А еще должна быть третья таблица, в которой хранится отношение фильма к жанрам, по которой и строить джоин.

Спустя 35 секунд (19.09.2011 - 18:42) inpost написал(а):
Krevedko
Можно при формировании таблицы ещё редактировать.
Допустим такая же выборка, только ORDER BY `name`.
Потом проверяешь, если имя нынешнего совпадает с предыдущим, то дописываешь жанр, если имя другое - то следующий фильм уже.

Это если без пагинатора, а с ним, сейчас подумаю smile.gif

Спустя 29 секунд (19.09.2011 - 18:42) vital написал(а):
А извиняюсь. Такая таблица уже есть. Верно. Далее побалуйтесь с джоинами. Они разные бывают wink.gif

И Group By

И парсить результат выборки тоже можно, убирая лишнее.

Спустя 2 минуты, 52 секунды (19.09.2011 - 18:45) Krevedko написал(а):
я думал об этом ...в том-то и дело, что все с пагинатором. и GROUP BY пробовал. тогда отрезает все жанры кроме одного при объединении строк

Спустя 2 минуты (19.09.2011 - 18:47) Kuliev написал(а):
Цитата (Krevedko @ 19.09.2011 - 19:45)
я думал об этом ...в том-то и дело, что все с пагинатором. и GROUP BY пробовал. тогда отрезает все жанры кроме одного при объединении строк

DISTINCT не поможет?

Спустя 47 секунд (19.09.2011 - 18:48) vital написал(а):
Цитата (inpost @ 19.09.2011 - 17:42)
Krevedko
Можно при формировании таблицы ещё редактировать.
Допустим такая же выборка, только ORDER BY `name`.
Потом проверяешь, если имя нынешнего совпадает с предыдущим, то дописываешь жанр, если имя другое - то следующий фильм уже.

Это если без пагинатора, а с ним, сейчас подумаю smile.gif

Второй запрос с count(), т.к. sql_calc_found_rows вернет не то wink.gif

Спустя 1 минута, 16 секунд (19.09.2011 - 18:49) inpost написал(а):
Krevedko
SELECT все фильмы. Получили список. while - создали массив. На основании этого массива и используешь пагинатор!


Далее второй (ОТДЕЛЬНЫЙ) запрос, WHERE `id_фильмы` IN (тут перечень фильмов, которые выводятся НА ЭТОЙ странице), получишь все жанры, далее сгруппируешь просто оба массива (2 разных, первый фильмы, второй жанры с ссылкой на фильм).

Понятно объяснил?! smile.gif

Спустя 2 минуты, 3 секунды (19.09.2011 - 18:51) vital написал(а):
Цитата (inpost @ 19.09.2011 - 17:42)
Krevedko
Можно при формировании таблицы ещё редактировать.
Допустим такая же выборка, только ORDER BY `name`.
Потом проверяешь, если имя нынешнего совпадает с предыдущим, то дописываешь жанр, если имя другое - то следующий фильм уже.

Это если без пагинатора, а с ним, сейчас подумаю :)

Делать селект всех фильмов зло. А если их пару мильенов, как на imdb ?
Лимит в джоины добавляется как-то так:
SELECT b.content AS atc_content, b.type AS atc_type, b.id AS atc_id, b.msg_id AS atc_msg_id, a.msg_id, a.msg_content, a.msg_author,a.msg_likes
FROM attachments b
RIGHT JOIN (
SELECT id AS msg_id, content AS msg_content, author AS msg_author, likes AS msg_likes
FROM messages
ORDER BY id DESC LIMIT ' . $page * $numberonpage . ',' . $numberonpage . '
) a
ON b.msg_id = a.msg_id

Так не обрежет жанры, (в моем случае вложения), но выберет только требуемое кол-во фильмов(у меня сообщений).

А потом парситься вывод на стороне пхп, составляя нормальный массив для вывода.

Спустя 1 минута, 3 секунды (19.09.2011 - 18:52) vital написал(а):
Так что товарищ администартор, учита матчасть wink.gif))

Спустя 29 секунд (19.09.2011 - 18:53) inpost написал(а):
vital
Я выше показал запрос, который даст лучше производительность, чем у тебя.

Спустя 1 минута, 59 секунд (19.09.2011 - 18:55) vital написал(а):
Цитата (inpost @ 19.09.2011 - 17:53)
vital
Я выше показал запрос, который даст лучше производительность, чем у тебя.

На 10 фильмах - да.
Когда их будет с 100 тыщ - нет.

Спустя 1 минута, 46 секунд (19.09.2011 - 18:56) inpost написал(а):
vital
SELECT * FROM `fims` LIMIT 10,10 - и чем же он будет плох на 100 тыс. записей?

Спустя 2 минуты, 51 секунда (19.09.2011 - 18:59) Krevedko написал(а):
лимит ессно используется. думаю надо действительно отобрать скажем 10 записей уникальных (дистинкт тот же заюзать) для пагинатора, а потом для этих записей еще проверить жанры, сколько их.

как я хочу:
user posted image

Спустя 1 минута, 2 секунды (19.09.2011 - 19:00) vital написал(а):
Цитата
SELECT все фильмы

Это без лимита.
А если лимит - то надо добавить sql_calc_found_rows - что бы получить общее количество, для пагинатора(про него ведь ты забыл, верно?)
И sql_calc будет производительнее, чем джоин.

Но все-равно, тут надо проверять кмк, что бы знать точно. Мне кажется на большом количестве записей Join > 2 запроса, в данном случае. Но точно не знаю, увы.

Спустя 1 минута, 57 секунд (19.09.2011 - 19:02) inpost написал(а):
Krevedko
Обращайся сразу к первой таблице, к таблице с фильмами, и никакой distinct не нужен будет.
Только при втором запросе уже когда брать будешь жанры, обращаться к таблице посреднику.

vital
СЕЛЕКТ ВСЕ ФИЛЬМЫ - это передача сути. Понятное дело мы обсуждаем вопрос с пагинатором, и второй фразой я уточнил ,что будет именно работа пагинатора, а значит ВСЕ ФИЛЬМЫ никак не будут выбраны, а лишь 10-15-20, сколько надо. Я думаю, креведко понял о чём я говорю smile.gif

Спустя 1 минута, 27 секунд (19.09.2011 - 19:04) vital написал(а):
Ну возможно у меня Горе от ума конечно, но проверять лень. Оставим как есть.
Ну и да, я зануда. Раз не было написано, про лимит\или общее кол-во, вот я и придрался.

Спустя 6 минут, 21 секунда (19.09.2011 - 19:10) Nikitian написал(а):
Читать и запоминать, велосипедистов не слушать, велосипеды не изобретать.

Спустя 44 минуты, 38 секунд (19.09.2011 - 19:55) vital написал(а):
Офигеть. Спасибо за ссылку.

Спустя 1 минута, 58 секунд (19.09.2011 - 19:57) Krevedko написал(а):
ага. осталось понять как это сделать в кохане. в квери билдере такого увы нет. с обычным запросом прийдется мучать

Спустя 8 минут, 21 секунда (19.09.2011 - 20:05) Krevedko написал(а):
расчехлил для квери билдера ура..через
$query_g = DB::expr(' GROUP_CONCAT(cat.name) ');

Спустя 5 минут, 6 секунд (19.09.2011 - 20:10) Krevedko написал(а):
задачка нумер два...список через запятую выводится, все круто. как сделать теперь каждый жанр ссылкой ? ) распарсить для каждого фильма жанры и искать в таблице ?

ЗЫ вопрос снят. все гуд !

Спустя 2 часа, 1 минута, 29 секунд (19.09.2011 - 22:11) forza написал(а):
Krevedko,
я конечно извиняюсь, но я что то похожее сейчас делаю тоже;) но поскольку опыт в таком роде проэкта нету, не могли бы вы разъяснить структуру базы данных какая он должна быть? Что-то наподобие

Cat
id , Title

Book
id, catid, title

Спустя 43 минуты, 33 секунды (19.09.2011 - 22:55) Krevedko написал(а):
cat
id, name

book
id, name

cat_book
id_cat, id_book

Спустя 9 часов, 33 минуты, 53 секунды (20.09.2011 - 08:29) forza написал(а):
блaгодарен
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.