2017-01-27 4 views
0

Я пытаюсь получить результат информации о строках из таблиц с именем book_info и copy_info, а затем (если они существуют) результаты из таблицы с именем издателя (чей внешний ключ находится в copy_info), и (если они существуют) являются результатом жанра имени таблицы через таблицу переходов, называемую books_genres. Ниже, $ safe_copy_id определяется в выражении php, я оставил его для примера.

Это работает:Несколько взаимодействий, работающих независимо, но не вместе

SELECT * FROM book_info, copy_info 
LEFT OUTER JOIN publisher ON copy_info.publisher_id = publisher.publisher_id 
WHERE book_info.book_id = copy_info.book_id 
AND copy_info.copy_id = $safe_copy_id LIMIT 1 

и это работает:

SELECT * FROM book_info, copy_info, books_genres 
LEFT OUTER JOIN genre ON books_genres.genre_id = genre.genre_id 
WHERE book_info.book_id = copy_info.book_id 
AND copy_info.copy_id = $safe_copy_id LIMIT 1 

Но то, что я действительно хотел бы работать так:

SELECT * FROM book_info, copy_info, books_genres 
LEFT OUTER JOIN publisher ON copy_info.publisher_id = publisher.publisher_id 
LEFT OUTER JOIN genre ON books_genres.genre_id = genre.genre_id 
WHERE book_info.book_id = copy_info.book_id 
AND copy_info.copy_id = $safe_copy_id LIMIT 1 

ли это, что я должен что-то гнездящихся Вот? Не уверен, как двигаться вперед и ценит любое понимание.

+3

Простое правило: * Никогда * не используйте запятые в предложении 'FROM'. * Всегда * используйте правильный, явный синтаксис JOIN. Вероятно, это поможет решить вашу проблему. –

+0

@GordonLinoff Я удалил запятые из предложения FROM. Я не уверен, что это то, что вы имели в виду, но я удалил «LEFT OUTER» из каждого условия соединения, чтобы просто сказать JOIN. К сожалению, это не сработало. –

+0

Я не уверен, как работает второй запрос. Не существует условия соединения для 'books_genres' с помощью' book_info' или 'copy_info'. Вы ищете декартовой продукт из 'book_genres'? Это поможет, если вы дадите 2 строки для всех таблиц и ваш ожидаемый результат на основе этого. – Utsav

ответ

0

Просто используйте JOIN правильно:

SELECT * 
FROM book_info bi JOIN 
    copy_info ci 
    ON bi.book_id = ci.book_id JOIN 
    publisher p 
    ON ci.publisher_id = p.publisher_id JOIN 
    books_genres bg 
    ON bg.book_id = bi.book_id JOIN -- your question doesn't specify the JOIN condition here 
    genre g 
    ON bg.genre_id = g.genre_id 
WHERE ci.copy_id = $safe_copy_id 
LIMIT 1; 

Вы пропускаете присоединиться к book_genres. Возможно, он связан с book_info.

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

+0

Вы правы, что books_genres связан с информацией о книге, я попытался запустить этот точный запрос, заменив его на правильную ссылку, и он все еще не работает. Благодарим вас за исправление моего синтаксиса. –

+0

Я использовал внешние соединения, потому что не все экземпляры copy_id будут иметь строки, возвращаемые из издателя или таблиц жанров. Я не уверен конкретно, почему, но он возвращает null, если я использую только JOIN, тогда как если я использую внешнее соединение, он возвращает только null для конкретного столбца (например, genre_id). Это мое лучшее объяснение моего опыта, я не знаю, если это правильное использование внешних объединений. –

+0

@KaariLandry. , , Кажется разумным. Просто замените все 'JOIN' 'LEFT JOIN'. –

0

Спасибо Гордону Линоффу и Утсаву за то, что я не присоединился к book_genres. Вот запрос, который действительно сработал:

SELECT * FROM 
book_info bi JOIN copy_info ci 
ON bi.book_id = ci.book_id 
LEFT OUTER JOIN publisher p 
ON ci.publisher_id = p.publisher_id 
LEFT OUTER JOIN books_genres bg 
ON bg.book_id = bi.book_id 
LEFT OUTER JOIN genre g 
ON bg.genre_id = g.genre_id 
WHERE ci.copy_id = $safe_copy_id 
LIMIT 1;