Новости
Документация
Download
Webboard
Поиск
FAQ/ЧаВо
Обратная связь




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, версию программного обеспечения, по которому возникает вопрос, текст возникающих ошибок, и др.)
Помните, чем конкретнее Вы опишете ситуацию, тем больше шансов получить реальную помощь.
 Имя:
 E-mail:
 Тема:
 Текст:
Код подтверждения отправки: Code
33023



РЕКЛАМА НА САЙТЕ
  Создание сайтов | |