MySQL Left Outer Join и объединение результатов - PullRequest
3 голосов
/ 28 декабря 2011

Я борюсь с объединением.По сути, я хочу, чтобы результаты тегов из моего запроса были в одной строке.

Ниже приведены мои таблицы:

  • cover
  • category
  • cover_tag
  • tag

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

В базе данных у меня есть 2 строки в обложках.Первая обложка имеет 3 ярлыка, вторая обложка не имеет ярлыков.При выполнении запроса ниже я получаю 4 строки.3 из них - 1-я обложка с другим тегом, 4-й - строка без каких-либо тегов.

Я хочу получить 2 результата со всеми тегами для каждой обложки в одном ряду.Возможно ли это?

SELECT * 
FROM cover
JOIN category ON cover.category_id = category.id
LEFT OUTER JOIN cover_tag ON cover_tag.cover_id = cover.id
LEFT OUTER JOIN tag ON cover_tag.tag_id = tag.id

Данные от phpMyAdmin

CREATE TABLE `category` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `slug` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

INSERT INTO `category` VALUES(1, 'Cars', 'cars');
INSERT INTO `category` VALUES(2, 'Music', 'music');
INSERT INTO `category` VALUES(3, 'Abstract', 'abstract');

CREATE TABLE `cover` (
   `id` int(9) NOT NULL AUTO_INCREMENT,
   `category_id` int(9) NOT NULL,
   `title` varchar(255) NOT NULL,
   `slug` varchar(255) NOT NULL,
   `image` varchar(255) NOT NULL,
   `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

INSERT INTO `cover` VALUES(1, 1, 'Red Ferarri', 'red-ferarri', 'redferrari.jpg', '2011-12-20    23:48:11');
INSERT INTO `cover` VALUES(2, 1, 'Ford Focus ST', 'ford-focus-st', 'focuss.jpg', '2011-12-20 23:48:11');

CREATE TABLE `cover_tag` (
   `cover_id` int(9) NOT NULL,
   `tag_id` int(9) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `cover_tag` VALUES(1, 1);
INSERT INTO `cover_tag` VALUES(1, 2);
INSERT INTO `cover_tag` VALUES(1, 3);

CREATE TABLE `tag` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `tag` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

INSERT INTO `tag` VALUES(1, 'cars');
INSERT INTO `tag` VALUES(2, 'ferarri');
INSERT INTO `tag` VALUES(3, 'speed');

1 Ответ

4 голосов
/ 28 декабря 2011

Вы можете объединить их с помощью GROUP_CONCAT с группировкой, что-то вроде этого:

Select c.title, GROUP_CONCAT(t.tag SEPARATOR ', ')   
From cover c
Join cCategory ct on c.Category_Id = ct.id
LEFT OUTER JOIN cover_tag ctg ON c.Id = ctg.cover_id
LEFT OUTER JOIN tag t on ctg.tag_id = t.id
GROUP By c.title

Это даст вам следующее:

   title          Tags
------------------------------------
Ford Focus ST   {NULL}
 Red Ferarri    cars, ferarri, speed
...