Question

C'est très similaire à Limiter les résultats de la table jointe à une ligne, mais j'ai du mal à le faire fonctionner exactement comme j'ai besoin ...

La structure du tableau est très similaire:

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)
);

Remplir les tables avec:

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);

Je veux faire un Select qui renvoie les 3 produits, avec des images appropriées. Semblable à:

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

Une solution simple serait:

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

Mais cela échoue si je veux ajouter et renvoyer un autre champ de tblProductImages (AltText par exemple)

J'ai configuré un violon à http://sqlfiddle.com/#!2/883C5/1

Merci

Était-ce utile?

La solution

Celui-ci fonctionnera, mais est assez laid

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;

alternative :

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

Autres conseils

Vous devez utiliser l'agrégation (en particulier GROUP BY). Vous voulez GROUP BY le nom du produit et utilisez un LEFT JOIN de sorte que l'image n'a pas besoin d'exister.

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

Notez que l'image sélectionnée dans ce cas est Aléatoire (bien que ce sera généralement dans intImageID ordre). Cela suppose que l'image réelle récupérée n'est pas importante tant qu'elle est associée au produit donné.

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

Pour cette sortie exacte, vous devrez peut-être modifier votre instruction d'insertion pour le tableau TBLProductImages comme:

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);

Et utilisez l'instruction SELECT ci-dessous:

SELECT tP.intProductID, tp.strProductName, tPI.strImageName
FROM tblProducts AS tP 
INNER JOIN tblProductImages AS tPI ON tP.intProductID = tPI.intProductID;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top