Я хочу объединить две таблицы MySQL, но использовать некоторые данные в одной из них как новые заголовки в объединенной.У меня есть две таблицы, например:
Журнал фруктов, которые мы ели каждый день.
<i>id</i> <i>date</i> <i>fruit</i>
5 2011-11-27 banana
4 2011-11-26 apple
3 2011-11-25 orange
2 2011-11-24 banana
1 2011-11-23 pear
Стол с тем, что мы думаем о фруктах, которые мы ели.
<i>id</i> <i>user</i> <i>fruit</i> <i>rating</i>
7 andrew banana yum
6 andrew apple eww
5 lisa apple yum
4 andrew orange yum
3 lisa orange yum
2 andrew pear eww
1 lisa pear eww
Я ищу SQL-запрос с результатом, похожим на этот:
<i>date</i> <i>fruit</i> <i>andrew</i> <i>lisa</i>
2011-11-27 banana yum NULL
2011-11-26 apple eww yum
2011-11-25 orange yum yum
2011-11-24 banana yum NULL
2011-11-23 pear eww eww
Полагаю, я не первый, кто хочет что-то подобное;но не очень легко найти ответ, когда вы не представляете, как его описать, за исключением показа таблиц и желаемого результата.
Для моих собственных экспериментов я сейчас фактически создал примерТаблицы я использую выше.(То, в чем я действительно нуждаюсь, концептуально схоже, но я фактически не знаю никого по имени Эндрю, и я не регистрирую фрукты, которые мы едим. Во всяком случае, реальные таблицы несколько больше и сложнее - они помогут описать концепцию.
--
-- Table structure `fruit_log`
--
CREATE TABLE IF NOT EXISTS `fruit_log` (
`id` int(11) NOT NULL auto_increment,
`date` date NOT NULL,
`fruit` varchar(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
--
-- Dumping of data in table `fruit_log`
--
INSERT INTO `fruit_log` (`id`, `date`, `fruit`) VALUES
(1, '2011-11-23', 'pear'),
(2, '2011-11-24', 'banana'),
(3, '2011-11-25', 'orange'),
(4, '2011-11-26', 'apple'),
(5, '2011-11-27', 'banana');
--
-- Table structure `fruit_log`
--
CREATE TABLE IF NOT EXISTS `fruit_ratings` (
`id` int(11) NOT NULL auto_increment,
`user` varchar(6) NOT NULL,
`fruit` varchar(6) NOT NULL,
`rating` enum('yum','eww') default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
--
-- Dumping of data in table `fruit_ratings`
--
INSERT INTO `fruit_ratings` (`id`, `user`, `fruit`, `rating`) VALUES
(1, 'lisa', 'pear', 'eww'),
(2, 'andrew', 'pear', 'eww'),
(3, 'lisa', 'orange', 'yum'),
(4, 'andrew', 'orange', 'yum'),
(5, 'lisa', 'apple', 'yum'),
(6, 'andrew', 'apple', 'eww'),
(7, 'andrew', 'banana', 'yum');
Я многому научился, пытаясь найти ответ на этот вопрос. Для начала, "сводные таблицы" как концепция, представленная мне @ w0051977. Ссылка на w0051977как бы это ни было специфично для Microsoft SQL Server - я использую MySQL. В любом случае, я познакомился с этой концепцией и посмотрел дальше. Я узнал кое-что из Википедии и многое из этой хроники: http://dev.mysql.com/tech-resources/articles/wizard/print_version.html
Однако, у меня естьЯ не смог найти ничего, что хотя бы отдаленно напоминало мою цель. Трудная часть, похоже, использует динамическое количество данных ячейки (данные из столбца «user»: «andrew» и «lisa» в моем примере, но могут также включать «bob "и, возможно, даже" alice "и т. д.) и" переворачивает "их, чтобы вместо этого действовать как заголовки столбцов.
Мастер делает это в хроникеСвязано выше, но не в одном запросе: он использует хитрый SQL-трюк для генерации части другого SQL-запроса, который можно вставить в запрос, который делает то, что хотел с самого начала.Конечно, вам не нужно на самом деле копировать и вставлять его - мастер автоматизирует его с помощью Perl, а я бы сделал это с помощью PHP (это часть проекта на основе PHP).Но если мне все равно придется использовать PHP для генерации запроса, я мог бы также сделать это более простым способом.
@ adam-wenger предложил использовать LEFT JOIN, но отметил, что он будет использоваться только для ограниченногоКоличество пользователей.Это его запрос, адаптированный к именам таблиц, которые я представил выше при редактировании после публикации его ответа.
SELECT fruit_log.date, fruit_log.fruit, a.rating AS 'andrew', l.rating AS 'lisa'
FROM fruit_log
LEFT JOIN fruit_ratings AS a
ON fruit_log.fruit = a.fruit
AND a.user = 'andrew'
LEFT JOIN fruit_ratings AS l
ON fruit_log.fruit = l.fruit
AND l.user = 'lisa'
ORDER BY date DESC
С помощью PHP я могу генерировать столько ЛЕВЫХ СОЕДИНЕНИЙ, сколько мне нужно, что решает мою проблему.Я также могу использовать подзапросы, например:
SELECT fruit_log.date, fruit_log.fruit, (
SELECT fruit_ratings.rating
FROM fruit_ratings
WHERE fruit_ratings.user = 'andrew'
AND fruit_ratings.fruit = fruit_log.fruit
) AS 'andrew', (
SELECT fruit_ratings.rating
FROM fruit_ratings
WHERE fruit_ratings.user = 'lisa'
AND fruit_ratings.fruit = fruit_log.fruit
) AS 'lisa'
FROM fruit_log
ORDER BY date DESC
Полагаю, один из них более эффективен, чем другой, но я не знаю, какой из них (если у меня есть время и интерес, яЯ сделаю тест некоторое время, если кто-то не предоставит информацию до того, как это произойдет).
Если у кого-то есть решение одной проблемы для моей проблемы, это будет очень признательно.До тех пор;Мне придется придерживаться PHP ducttape (и этот вопрос останется без ответа).