Объединение запроса с несколькими таблицами на основе значений

#php #mysql

#php #mysql

Вопрос:

Предполагается, что у меня есть таблица posts , подобная приведенной ниже:

 |    id    |     type     |     ref_id     |
----------- --------------  ---------------
|    1     |      1       |      1         |
|    2     |      1       |      2         |
|    3     |      3       |      3         |
|    4     |      1       |      4         |
|    5     |      2       |      5         |
|    6     |      3       |      6         |
 

Поле типа предназначено для объединения с другими таблицами, так, например, 1 = блоги, 2 = обзоры, 3 = фотографии, и у каждого из них есть соответствующие поля, а ref_id — это идентификатор блога / обзора / фотографии.

Что я хочу сделать, так это показать все последние сообщения (порядок по идентификатору DESC), при этом объединяясь со всеми другими таблицами на основе значения типа, но я хочу сделать это с помощью одного запроса, если это возможно. Мой бесполезный запрос приведен ниже:

 SELECT * FROM posts
LEFT JOIN blogs ON posts.ref_id = blogs.ID AND posts.type = 1
LEFT JOIN reviews ON posts.ref_id = reviews.ID AND posts.type = 2
LEFT JOIN photos ON posts.ref_id = photos.ID AND posts.type = 3
ORDER BY posts.id DESC
 

Запрос ни к чему не приводит. Другой альтернативой является цикл запроса SELECT * FROM posts и выполнение другого запроса на основе типа, но, если возможно, я бы хотел сделать это за 1 раз.

Спасибо за помощь.

Комментарии:

1. Вам нужно заключить предложение ON в квадратные скобки?

2. Я вижу ошибки sevaral. Во-первых, я не вижу необходимости в AND . Вы можете поместить все в класс WHERE. Во-вторых, вы используете posts.type_id, которого нет в вашей таблице.

3. @BenjieGillam : что вы имеете в виду? Я не думаю, что это имеет значение? AurelioDeRosa: Я отредактировал свой вопрос, это опечатка. Что вы имеете в виду в предложении WHERE? Я не собираюсь использовать определенный ref_id, я хочу получить все сообщения, мне просто нужно найти способ подключить ref_id к правильной таблице на основе типа.

4. Вам нужны все сообщения? Или последнее сообщение?

5. @ypercube : на самом деле это не имеет значения. Последнее — это в основном все сообщения, упорядоченные по DESC и ограниченные определенным числом, а не суть моего вопроса

Ответ №1:

Чтобы понять, почему ваш запрос ничего не возвращает, рассмотрите возможность перемещения » AND posts.type = » из JOIN в WHERE предложение. Это будет:

 select * from posts ... where type=1 and type=2 and type=3
 

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

(имя таблицы: поля)

 posts: id
blogs: id, post_id
reviews: id, post_id
photos: id, post_id
 

В этом случае вы сможете создавать более простые и традиционные запросы:

 select * from posts
    left join blogs on blogs.post_id = posts.id
    left join reviews on reviews.post_id = posts.id 
    left join photos on photos.post_id = posts.id 
 

Комментарии:

1. хорошая идея, но я должен сначала подумать обо всей картине, прежде чем пробовать ваше предложение, потому что фактический случай довольно сложный

2. я пробовал вашу идею, но она не работает. Результат запроса отображает только последнюю объединенную таблицу

Ответ №2:

Я думаю, вы хотите что-то вроде этого:

 (   SELECT posts.*, blogs.*  
    FROM posts
      JOIN blogs 
        ON  posts.ref_id = blogs.ID 
        AND posts.type = 1
UNION ALL
    SELECT posts.*, reviews.* 
    FROM posts
      JOIN reviews 
        ON  posts.ref_id = reviews.ID 
        AND posts.type = 2
UNION ALL
    SELECT posts.*, photos.* 
    FROM posts
      JOIN photos 
        ON  posts.ref_id = photos.ID 
        AND posts.type = 3
)
ORDER BY posts.id DESC