SQL - самый эффективный способ выполнить этот запрос? - PullRequest
1 голос
/ 13 июля 2009

В основном у меня есть три таблицы, записи, изображения и изображения (это просто содержит идентификаторы обеих других таблиц и позволяет использовать более одного изображения в каждом сообщении, и каждое изображение можно повторно использовать в нескольких сообщениях при необходимости).

Я пытаюсь перечислить названия всех постов вместе с одним маленьким изображением из каждого (если оно есть)

Я могу сделать следующее:

    $sql ="SELECT * FROM posts p, images im, postimages pi WHERE
    AND pi.post_id = p.id
    AND pi.image_id = im.image_id
    ORDER BY created_at LIMIT 10";

Но, очевидно, если имеется более одного изображения, запись отображается дважды.

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

Любой совет будет оценен. Спасибо.

Ответы [ 2 ]

1 голос
/ 13 июля 2009
select
    *
from
    posts p
    left outer join (select post_id, max(image_id) as image_id 
        from postimages group by post_id) pi on
        p.id = pi.post_id
    left outer join images im on
        pi.image_id = im.image_id

Вы можете выполнить подзапрос, чтобы он выполнялся только один раз, а не для каждой строки. Таким образом, он используется как подзапрос для всей таблицы, а затем присоединяется к сообщениям. Очевидно, это может быть MIN(image_id), если вы хотите сделать первое изображение. На самом деле, что вы предпочитаете.

Редактировать: Сделано left outer join для захвата даже тех изображений, которых нет в сообщениях. Это вернет null для изображения в случае, если оно не существует.

0 голосов
/ 13 июля 2009
SELECT p.id,p.title,im.src
FROM posts p
LEFT JOIN postimages pi
ON p.id = pi.post_id 
LEFT JOIN images im
ON pi.image_id = im.image_id
GROUP BY p.id
ORDER BY created_at 
LIMIT 10

Не уверен, что это наиболее эффективно, вам придется выполнить это для внутреннего запроса. Насколько я знаю, он будет работать только для MySql.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...