LIMIT только на одну из таблиц в JOIN

У меня есть две таблицы product и gallery. Каждый продукт может иметь несколько изображений в gallery. Когда я пытаюсь получить LIMITed 5 продуктов вместе с их gallery записями, я делаю JOIN, например:

SELECT * FROM `product` p LEFT JOIN `gallery` g ON p.product_id = g.product_id 
LIMIT 0,5

Этот запрос возвращает мне 5 записей (т.е. только 3 продукта), например:

product_id   name   image
1            p1     im1.jpg
1            p1     im3.jpg
1            p1     xyz.jpg
2            p2     abc.jpg
3            p3     tuy.jpg

Мне нужно ровно 5 продуктов, независимо от того, сколько gallery записей для каждого продукта и сколько всего записей. Вот мой ожидаемый результат:

product_id   name   image
1            p1     im1.jpg
1            p1     im3.jpg
1            p1     xyz.jpg
2            p2     abc.jpg
3            p3     tuy.jpg
4            p4     a32.jpg
4            p4     t22.jpg
4            p4     a13c.jpg
5            p5     t34y.jpg

Как я могу сделать это с помощью одного запроса?


person arxoft    schedule 23.03.2014    source источник
comment
Вы можете опубликовать ожидаемый результат? Вы имеете в виду, что вам нужны разные продукты?   -  person DevelopmentIsMyPassion    schedule 23.03.2014
comment
@AshReva Пожалуйста, проверьте, я отредактировал   -  person arxoft    schedule 23.03.2014


Ответы (3)


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

SELECT * FROM
 `gallery` g
INNER JOIN 
(SELECT * FROM  `product` LIMIT 5) p
 ON( p.product_id = g.product_id )
person M Khalid Junaid    schedule 23.03.2014
comment
Спасибо. Почему бы не LEFT JOIN? - person arxoft; 23.03.2014
comment
Left вернет все изображения, даже не относящиеся к 5 продуктам из подзапроса, поэтому я использую внутреннее соединение - person M Khalid Junaid; 23.03.2014
comment
Что, если я использую LEFT JOIN и WHERE g.product_id IS NOT NULL - person arxoft; 23.03.2014
comment
Да, это будет работать так же, как внутреннее соединение, используя вышеприведенное предложение where - person M Khalid Junaid; 23.03.2014

Вы можете изменить свой запрос следующим образом:

SELECT * FROM `product` p LEFT JOIN (SELECT * FROM `gallery` LIMIT 0,5) as g ON    p.product_id = g.product_id 

Но использование подзапроса снижает производительность.

person ashish    schedule 23.03.2014

Чтобы получить пять изображений для каждого продукта (что является неправильным толкованием вопроса):

SELECT *
FROM `product` p LEFT JOIN
     `gallery` g
     ON p.product_id = g.product_id 
WHERE 5 <= (select count(*)
            from gallery g2
            where g2.product_id = g.product_id and g2.image <= g.image
           );

Альтернативный способ — поместить изображения в один столбец, разделенный запятыми:

select p.*, substring_index(group_concat(distinct image), ',', 5) as images
from product p left join
     gallery g
     on p.product_id = g.product_id
group by p.product_id;
person Gordon Linoff    schedule 23.03.2014
comment
Спасибо, но вариант @M Khalid проще. - person arxoft; 23.03.2014
comment
@ацеф . . . Нет. Тот ответ правильный, а этот нет, потому что я ответил не на тот вопрос. Я все равно оставлю это. - person Gordon Linoff; 23.03.2014