Как сделать фильтр отбора на сайте

Rayzor92

Новичок
Мне нужно отобрать записи о фильмах из базы данных. Структуру таблиц я сделал такой:
таблица с фильмами
таблица с жанрами
таблица с 2 полями: фильм и жанр.
причём жанров можно выбрать несколько, ну и ещё параметры: год, режиссёр, которые хранятся в таблице фильмов. Как sql запрос составить? я взял и склеил таблицы по join но у меня в выборке один фильм дублируется столько раз, сколько жанров у него найдётся. А как сделать без дублирования?
или как потом обработать эти массивы, чтобы жанры выводились в одной ячейке.
 

WMix

герр M:)ller
Партнер клуба
собрать индификаторы фильмов, собрать жанры для этих фильмов, склеить правильно результаты
 

Rayzor92

Новичок
я кажется понял, вы имеете в виду достать все фильмы, потом в цикле к каждому фильму доставать жанры и записывать их подмассивом в массив игр? Тогда к бд будет n+1 запрос, где n-это количество фильмов. Это нормально? Если я допустим вывожу 100 фильмов, то будет 101 запрос к БД.
 

WMix

герр M:)ller
Партнер клуба
нет я предложил всего 2 запроса.
найти все необходимые фильмы sql1
выудить все индификаторы фильмов
вытянуть все жанры для найденных фильмов sql2
PHP:
where film_id IN ( x,y,z,... )
склеить
 

Rayzor92

Новичок
а как я потом из php идентификаторы в sql передам? Объясните по нормальному
 

WMix

герр M:)ller
Партнер клуба
в примере использовал safemysql
не тестил, но идею думаю увидешь!

PHP:
$films = $db->getAll('select * from film where ... ');
$film = array();
foreach( $films as $row ){
 $film[ $row['id'] ] = $row;
}
$genres = $db->getAll(
    'select * from genre left join ... where film_id in ( ?a )', 
    array_keys($film)
);
foreach( $genres as $row ){
 $film[ $row['film_id'] ]['genres'][  ] = $row;
}

print_r($film);
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
в примере использовал safemysql
О, круто! Но вообще-то индексация есть из коробки:
PHP:
$films = $db->getInd('id','select * from film where ... ');
$genres = $db->getAll(
    'select * from genre where left join ... film_id in ( ?a )', 
    array_keys($films)
);
:)
Но вообще я бы делал по-другому.

Rayzor92 чтобы не было повторов, тебе нужна ГРУППИРОВКА
в приведенном ниже запросе жанры фильма будут перечислены через запятую.
дальше их только отэксплодить и заполнить
PHP:
$genres = $db->getInd('id', 'SELECT * FROM genre'), 
// если от жанра нужно только название, то
$genres = $db->getIndCol('id', 'SELECT name FROM genre'), 

$sql    = 'SELECT f.*,GROUP_CONCAT(fg.gid) genresFROM film f LEFT JOIN films_genres fg ON fg.fid = f.id WHERE ... GROUP BY fid';
$res    = $db->query($sql);
$films  = array();
while($row = $db->fetch($res))
{
    $tmp = array();
    foreach(explode($row['genres']) as $gid)
    {
        $tmp[$gid] = $genres[$gid];
    }
    $row['genres'] = $tmp;
    $films[]       = $row;
}
Про safemysql можно почитать по-русски
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
О, круто! Но вообще-то индексация есть из коробки:
не хотел чтоб помидорами забросали :), а safemysql довольно наглядная и простая библиотечка, в которой действительно легко должен разобраться новичек.
$db->getInd() да, одним перебором меньше!
а про GROUP_CONCAT, я сначала было подумал, но 2 момента меня остановило

1. хочу делать простые запросы и обрабатывать на клиенте базы, чтоб облегчить базу
2. GROUP_CONCAT имеет ограниченную длину.

оба высказывания уверен не сильно относятся к ТС, просто медленно с вашей помощью меняется и мой разум.
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Кстати, да. Насчет GROUP_CONCAT верное замечание.
Надо не забывать делать побольше через SET group_concat_max_len
В прочем, для списка жанров, который всяко будет меньше десятка, ограничение в сотню айдишников явно не будет превышено
 

Rayzor92

Новичок
ребят а у меня GROUP_CONCAT двои данные иногда. Т.е если айдишник 1, то он может написать 1,1. Лазию вот по фильмам и где-то двоит, а где то нормально
 
Сверху