Ограничить результаты объединенной таблицы до одной строки

Вот упрощенная структура таблицы:

TABLE products (
 product_id INT (primary key, auto_increment),
 category_id INT,
 product_title VARCHAR,
 etc
);

TABLE product_photos (
 product_photo_id (primary key, auto_increment),
 product_id INT,
 photo_href VARCHAR,
 photo_order INT
);

У продукта может быть несколько фотографий, первая фотография продукта для каждого продукта (на основе фото_области) является фотографией по умолчанию.

Теперь мне нужны только все фотографии на странице сведений о продукте, но на страницах, где я перечисляю несколько продуктов, например страницу каталога продуктов, я хочу показывать только фотографию по умолчанию.

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

Это, очевидно, не работает, оно вернет все фотографии с информацией о товаре, дублированной для каждой фотографии:

SELECT p.*, ph.*
FROM products AS p
LEFT JOIN product_photos AS ph
ON p.product_id=ph.product_id
ORDER BY p.product_title ASC

Мне нужно выяснить, как это сделать, но я не знаю синтаксиса (или если это возможно)

SELECT p.*, ph.*
FROM products AS p
LEFT JOIN product_photos AS ph
    ON p.product_id=ph.product_id  **ORDER BY ph.photo_order ASC LIMIT 1**
ORDER BY p.product_title ASC

Изменить: я понял решение с помощью ответов ниже, спасибо всем!

SELECT p.*, ph.*
FROM products AS p
LEFT JOIN product_photos AS ph 
    ON p.product_id=ph.product_id
    AND ph.photo_order =
    (
        SELECT MIN(z.photo_order)
        FROM product_photos AS z
        WHERE z.product_id=p.product_id
    )
GROUP BY p.product_id
ORDER BY p.product_title ASC

Ответы

Ответ 1

Использование:

SELECT p.*,
       pp.*
  FROM PRODUCTS p
  JOIN PRODUCT_PHOTOS pp ON pp.product_id = p.product_id
  JOIN (SELECT x.product_id,
               MIN(x.photo_order) AS default_photo
          FROM PRODUCT_PHOTOS x
      GROUP BY x.product_id) y ON y.product_id = pp.product_id
                              AND y.default_photo  = pp.photo_order

Ответ 2

SELECT p.*, ph.*
FROM products AS p
INNER JOIN product_photos AS ph
    ON p.product_id = ph.product_id
LEFT JOIN product_photos AS ph2
    ON p.product_id = ph2.product_id
    AND ph2.photo_order < ph.photo_order
WHERE ph2.photo_order IS NULL
ORDER BY p.product_title ASC

Обратите внимание на то, как он дважды присоединяется к таблице product_photos. WHERE ph2.photo_order IS NULL выкинет все, кроме самого низкого порядка фото. Он не будет защищать вас от дублирования product_id/photo_orders, но вы можете добавить GROUP BY на p.id, если это дело.

Ответ 3

    SELECT p.*, ph.*
    FROM products AS p
    LEFT JOIN product_photos AS ph ON p.product_id=ph.product_id
    ORDER BY p.product_title ASC, ph.photo_order ASC
    GROUP BY p.product_id
    LIMIT 0,10

Ответ 4

SELECT ...
  ....
GROUP BY p.product_id