Frage

Dies ist sehr ähnlich zu Begrenzen Sie die Ergebnisse von der zusammengefügten Tabelle auf eine Zeile, aber ich kämpfe darum, es genau so zu arbeiten, wie ich brauche ...

Die Tabellenstruktur ist sehr ähnlich:

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

Populieren Sie die Tische mit:

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

Ich möchte eine ausgewählte Auswahl durchführen, die alle 3 Produkte mit geeigneten Bildern zurückgibt. Ähnlich zu:

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

Eine einfache Lösung wäre:

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

Dies schlägt jedoch fehl, wenn ich ein anderes Feld aus den TBLProductimages hinzufügen und zurückgeben möchte (zum Beispiel AltText)

Ich habe eine Geige eingerichtet http://sqlfiddle.com/#!2/883c5/1

Vielen Dank

War es hilfreich?

Lösung

Dieser wird funktionieren, ist aber ziemlich hässlich

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

Andere Tipps

Sie müssen die Aggregation verwenden (speziell GROUP BY). Du möchtest GROUP BY der Produktname und verwenden a LEFT JOIN so dass das Bild nicht existieren muss.

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

Beachten Sie, dass das in diesem Fall ausgewählte Bild ist zufällig (Obwohl es normalerweise in sein wird intImageID bestellen). Dies setzt voraus, dass das tatsächliche abgerufene Bild nicht wichtig ist, solange es mit dem angegebenen Produkt verbunden ist.

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

Für diese genaue Ausgabe müssen Sie möglicherweise Ihre Einfügeanweisung für Tabelle tBlProductimages als:

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

Und verwenden Sie die folgende Auswahlanweisung:

SELECT tP.intProductID, tp.strProductName, tPI.strImageName
FROM tblProducts AS tP 
INNER JOIN tblProductImages AS tPI ON tP.intProductID = tPI.intProductID;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top