MySQL为每个产品返回1个图像

时间:2013-12-03 14:10:01

标签: mysql

这与Limit results from joined table to one row非常相似,但我正在努力让它完全符合我的需要...

表结构非常相似:

CREATE TABLE tblProducts (
    intProductID int(11) NULL AUTO_INCREMENT,
    strProductName varchar(255) NULL,
    PRIMARY KEY (intProductID)
);

CREATE TABLE tblProductImages (
    intImageID int(11) NULL AUTO_INCREMENT,
    intProductID int(11) NULL,
    strImageName varchar(255) NULL,
    intOrder int(11) NULL,
    PRIMARY KEY (intImageID)
);

使用以下内容填充表格:

INSERT INTO tblProducts (strProductName)
VALUES
('Product #1'), ('Product #2'), ('Product #3');

INSERT INTO tblProductImages (intProductID, strImageName, intOrder) 
VALUES
(1, 'image_for_1.jpg', 1), 
(2, '1st_image_for_2.jpg', 1), 
(2, '2nd_image_for_2.jpg', 2);

我想做一个SELECT,返回所有3个产品,并带有适当的图像。类似于:

intProductID, strProductName, strImageName
1, Product #1, image_for_1.jpg
2, Product #2, 1st_image_for_2.jpg
3, Product #3, NULL

一个简单的解决方案是:

SELECT intProductID, strProductName, 
 (SELECT strImageName
  FROM tblProductImages
  WHERE tblProductImages.intProductID = tblProducts.intProductID
  ORDER BY intOrder
  LIMIT 1)
FROM tblProducts

但如果我想添加&从tblProductImages返回另一个字段(例如AltText)

我在http://sqlfiddle.com/#!2/883c5/1

设置了一个小提琴

由于

3 个答案:

答案 0 :(得分:1)

这个会起作用,但很难看

select p.intProductId, p.strProductName, pi.strImageName 
from tblProducts p
inner join tblProductImages pi on pi.intProductID = p.intProductId
inner JOIN (select min(intOrder) minOrder, intProductID
           FROM tblProductImages
           GROUP BY intProductID) s
           on s.intProductID = p.intProductID and s.minOrder = pi.intOrder
union
select p.intProductId, p.strProductName, pi.strImageName
from tblProducts p
left join tblProductImages pi on pi.intProductID = p.intProductId
where pi.intProductID is null;

替代方案:

select p.intProductId, p.strProductName, pi.strImageName
from tblProducts p
left join tblProductImages pi on pi.intProductID = p.intProductId
where pi.intProductId is null or pi.IntOrder = (select min(intOrder)
                                                from tblProductImages
                                                where intProductId = pi.intProductId);

Sqlfiddle

答案 1 :(得分:0)

您需要使用聚合(特别是GROUP BY)。您希望GROUP BY产品名称并使用LEFT JOIN,以便图片不需要存在。

SELECT strProductName, strImageName
FROM tblProducts LEFT JOIN tblProductImages USING (intProductID)
GROUP BY strProductName

请注意,在这种情况下选择的图像是随机(尽管通常它将是intImageID顺序)。这假设检索到的实际图像并不重要,只要它与给定的产品相关联即可。

http://sqlfiddle.com/#!2/1391e6/1

答案 2 :(得分:0)

对于该确切输出,您可能需要将table tblProductImages的insert语句修改为:

INSERT INTO tblProductImages (intProductID, strImageName, intOrder) VALUES
    (1, 'image_for_1.jpg', 1), (2, '1st_image_for_2.jpg', 1), (3, '2nd_image_for_3.jpg', 2);

并使用以下Select语句:

SELECT tP.intProductID, tp.strProductName, tPI.strImageName
FROM tblProducts AS tP 
INNER JOIN tblProductImages AS tPI ON tP.intProductID = tPI.intProductID;