2014-02-17 6 views
2

До сих пор я не добился успеха в моем поиске по объединению 4 таблиц. У меня есть 4 таблицы:Комплексный запрос MySQL из 4 таблиц

содержание

content_id | source_id | content_title | content_date 
-------------------------------------------------------- 
1   | 1   | The factory  | 189982398300 
2   | 2   | Cold and cloudy | 189982398299 
3   | 2   | Green tea  | 189982398298 

источники

source_id | source_name 
------------------- 
1   | BBC 
2   | Reuters 

настройки

setting_id | setting_name 
------------------------------- 
1   | bbc_iplayer_string 
2   | reuters_video_id 
3   | reuters_category 

content_join_settings

content_id | setting_id | setting_data 
------------------------------------------ 
1   | 1   | Js88sdhjsd0gDS09 
2   | 2   | video_8AJK3ADJD8 
2   | 3   | weather 
3   | 2   | video_K7KD8N2ND9 
3   | 3   | food and drinks 

Так как вы, возможно, уже заметили, каждая запись контента имеет собственный источник связан с ним, и поставляется с дополнительными настройками в зависимости от источника. В сообщениях BBC есть bbc_iplayer_string, а сообщения от Reuters - reuters_video_id и reuters_category. Конечно, это всего лишь пример.

Я хотел бы, чтобы результаты были объединены, а также с именем setting_name в качестве имени столбца. Я не знаю, как объяснить это, так что я буду показывать:

content_id | source_name | content_title | content_date | bbc_iplayer_string | reuters_video_id | reuters_category 
-------------------------------------------------------------------------------------------------------- 
1   | BBC   | The factory  | 189982398300 | Js88sdhjsd0gDS09 | NULL    | NULL 
2   | Reuters  | Cold and cloudy | 189982398299 | NULL    | video_8AJK3ADJD8 | weather 
3   | Reuters  | Green tea  | 189982398298 | NULL    | video_K7KD8N2ND9 | food and drinks 

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

SELECT 
    * 
FROM 
    content, 
    sources, 
    settings, 
    content_join_settings 
WHERE 
    content.content_id = content_join_settings.content_id AND 
    settings.setting_id = content_join_settings.setting_id AND 
    sources.source_id = content.source_id 
GROUP BY 
    content.content_id 
ORDER BY 
    content.content_date 
    DESC 
+0

вы пробовали внутреннее соединение еще? – Raiyan

+0

Почему группа? Большинство баз данных будут вызывать ошибку для этого в предложении group by ... MySQL не возвращает ошибку и делает неправильную вещь. Групповые данные для агрегатов и обычно не применяются к select *. Вы также используете старый синтаксис соединения ... вы не согласны с использованием внутреннего соединения tablea a on ... syntax? – Twelfth

+0

@raiyan - он делает внутреннее соединение, только старый синтаксис. – Twelfth

ответ

3

Вам необходимо присоединиться к таблицам, а затем повернуть результаты, чтобы переместить строки в столбцы.

SELECT c.content_id, s.source_name, c.content_title, c.content_date, 
     MAX(CASE setting_name WHEN 'bbc_iplayer_string' THEN setting_data END) AS bbc_iplayer_string, 
     MAX(CASE setting_name WHEN 'reuters_video_id' THEN setting_data END) AS reuters_video_id, 
     MAX(CASE setting_name WHEN 'reuters_category' THEN setting_data END) AS reuters_category 
FROM content AS c 
INNER JOIN sources AS s ON s.source_id = c.source_id 
INNER JOIN content_join_settings AS cjs ON cjs.content_id = c.content_id 
INNER JOIN settings as st ON st.setting_id = cjs.setting_id 
GROUP BY c.content_id 

DEMO

+0

Большое спасибо! Отлично работает! – Bob

+0

Я почти не осмеливаюсь спросить, так как вы уже много помогли мне, но у меня есть следующий вопрос: возможно ли динамическое имя 'setting_name'? Я использую много разных источников, у всех есть свои собственные настройки, это был бы очень длинный запрос в долгосрочной перспективе. – Bob

+0

Для этого вам нужно написать динамический SQL. Я посмотрю, смогу ли я найти ответ, который показывает это. – Barmar

-2

Это поможет?

SELECT 
    * 
FROM 
    content as ct inner join sources as ss on ct.source_id = ss.source_id 
    inner join content_join_settings as cst on ct.setting_id = cst.setting_id 
    inner join settings as st on st.setting_id = cst.setting_id 
GROUP BY 
    content.content_id 
ORDER BY 
    content.content_date 
    DESC 
+0

Поздравляем, вы успешно изменили свой синтаксис от старого к новому, но не приблизились к вопросу – Twelfth

+0

wow, -1 еще до того, как страница загрузится с момента отправки. помогите объяснить, почему? – Raiyan

+0

объяснение выше ...нет никакой проблемы с его синтаксисом, соединение в предложении where является более старым способом взглянуть на него, но все же функциональным. его вопрос состоял в том, что «я хотел бы, чтобы результаты были объединены, а с именем параметра как имя столбца», объясните, как вы ответили на это. – Twelfth

Смежные вопросы