|
MySQL.RU - Webboard
Вернуться
Отношение "многие ко многим" (Илья Коробков) 20/11/2001 - 13:52:35
Re: Отношение (Василий) 20/11/2001 - 15:32:49
Re: Отношение (dim-dim) 20/11/2001 - 20:48:37
Re: Отношение (Танечка) 23/02/2007 - 21:55:58
Re: Отношение (Cesar) 08/02/2008 - 03:54:34
Re: Отношение (Cesar) 09/02/2008 - 02:00:10
> Original message text:
> From: Илья Коробков - 20/11/2001 - 13:52:35
> Subject:Отношение "многие ко многим"
> -----------------
> Здравствуйте!
> Подскажите, пожалуйста, что и где в Интернете можно почитать про создание БД с использованием отношения "многие ко многим"? Что-то я даже в довольно толстой книжке "MySQL" Поля Дюбуа не нашел ничего на эту тему (что, вообще говоря, странно).
> Спасибо!
>
From: Cesar - 08/02/2008 - 03:54:34
Subject:Отношение
-----------------
Пожалуй продолжу тему своим вопросом.
Есть 2 таблицы, фильмы и жанры, строю отношение "многие ко многим" через связную таблицу, но возникла проблема с запросом.
Мне нужно получить список скажем 30 фильмов и список всех жанров каждого фильма при этом, желательно, одним запросом.
Немного шире на урезанной структуре и примере.
CREATE TABLE `films` (
`film_id` mediumint(8) unsigned NOT NULL auto_increment,
`film_name` varchar(30) NOT NULL,
PRIMARY KEY (`film_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=cp1251;
INSERT INTO `films` (`film_id`, `film_name`) VALUES (1, 'Film1'), (2, 'Film2'), (3, 'Film3');
-- --------------------------------------------------------
CREATE TABLE `filmgenres` (
`fg_id` mediumint(8) unsigned NOT NULL auto_increment,
`fg_filmid` mediumint(8) unsigned NOT NULL,
`fg_genreid` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`fg_id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=cp1251;
INSERT INTO `filmgenres` (`fg_id`, `fg_filmid`, `fg_genreid`) VALUES (1, 1, 1), (2, 1, 3), (3, 2, 2), (4, 2, 3), (5, 3, 4), (6, 3, 6);
-- --------------------------------------------------------
CREATE TABLE `genres` (
`genre_id` smallint(4) NOT NULL auto_increment,
`genre_name` varchar(30) NOT NULL,
PRIMARY KEY (`genre_id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=cp1251;
INSERT INTO `genres` (`genre_id`, `genre_name`) VALUES (1, 'Комедия'), (2, 'Фантасика'), (3, 'Боевик'), (4, 'Драма'), (5, 'Фэнтези'), (6, 'Триллер');
Запросы:
----------------------------------------------
1. SELECT film_name, genre_name FROM films JOIN filmgenres ON films.film_id=filmgenres.fg_filmid JOIN genres ON filmgenres.fg_genreid=genres.genre_id WHERE film_id = 1
Запрос выбирает поля из связных таблиц для фильма с id = 1, но при этом результат прийдет массивом из двух элементов, которые будут отличаться только жанром фильма (так как их два для фильма с id = 1)
Результат:
Array(
[0] => Array([film_name] => Film1, [genre_name] => Комедия),
[1] => Array([film_name] => Film1, [genre_name] => Боевик)
)
2. SELECT film_name, genre_name FROM films JOIN filmgenres ON films.film_id=filmgenres.fg_filmid JOIN genres ON filmgenres.fg_genreid=genres.genre_id
Запрос выбирает поля из связных таблиц для всех фильмов, но при этом результат будет массивом из 6-ти элементов (так как каждый из 3-х фильмов имеет по два жанра)
Результат:
Array(
[0] => Array([film_name] => Film1, [genre_name] => Комедия),
[1] => Array([film_name] => Film1, [genre_name] => Боевик),
[2] => Array([film_name] => Film2, [genre_name] => Фантасика),
[3] => Array([film_name] => Film2, [genre_name] => Боевик),
[4] => Array([film_name] => Film3, [genre_name] => Драма),
[5] => Array([film_name] => Film3, [genre_name] => Триллер)
)
3. SELECT film_name, genre_name FROM films JOIN filmgenres ON films.film_id=filmgenres.fg_filmid JOIN genres ON filmgenres.fg_genreid=genres.genre_id LIMIT 2
Запрос выбирает все поля из связных таблиц для одного фильма (хотя необходимо для 2-х), и при этом результат будет массивом из 2-х элементов (так как ограничили через LIMIT)
Array(
[0] => Array([film_name] => Film1, [genre_name] => Комедия),
[1] => Array([film_name] => Film1, [genre_name] => Боевик)
)
Вопрос: как построить запрос (и можно ли?) что бы им забрать поля по 2-м фильмам и их жанры?
Необходимо получить что-то типа того, что ниже, но LIMIT ограничивает в 2-е возвращаемые записи:
array(
[0] => array('film_name' => 'Film1', 'genres' => array('Комедия', 'Боевик')),
[1] => array('film_name' => 'Film2', 'genres' => array('Фантасика', 'Боевик'))
);
Или
array(
[0] => array('film_name' => 'Film1', 'genre' => 'Комедия'),
[1] => array('film_name' => 'Film1', 'genre' => 'Боевик'),
[2] => array('film_name' => 'Film2', 'genre' => 'Фантасика'),
[3] => array('film_name' => 'Film2', 'genre' => 'Боевик')
);
Попробовал еще и так, но работает ограничение на вложенный запрос , который должен возвращать только одно значение одного поля.
SELECT film_name, film_id AS fid, CONCAT_WS(',',(SELECT genre_name FROM filmgenres JOIN genres ON filmgenres.fg_genreid=genres.genre_id WHERE fg_filmid=fid)) AS genres FROM films LIMIT 2
Есть у кого какие идеи? Может структуру необходимо по другому сделать или даже не знаю как это реализовать. Может тут где-то и мелкая проблема, но почему-то не лезет в голову ее решение.
Надеюсь на вашу помощь. Заранее спасибо.
[Это сообщение - спам!]
Последние сообщения из форума
Уважаемые посетители форума MySQL.RU!
Убедительная просьба, прежде чем задавать свой вопрос в этом форуме, обратите внимание на разделы:
- ответы на наиболее часто задаваемые вопросы - FAQ
- раздел документация
- раздел поиск по сообщениям форума и документации
Также, старайтесь наиболее подробно указывать свою ситуацию (версию операционной системы, версию MySQL,
версию программного обеспечения, по которому возникает вопрос, текст возникающих ошибок, и др.)
Помните, чем конкретнее Вы опишете ситуацию, тем больше шансов получить реальную помощь.
33023
|
|