سؤال

هذا مشابه جدا ل الحد من النتائج من الجدول المرتبط بصف واحد, ، لكنني أعاني من أجل العمل تمامًا كما أحتاج ...

بنية الجدول متشابهة جدا:

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

أرغب في القيام باختيار يقوم بإرجاع جميع المنتجات الثلاثة ، مع الصور المناسبة. مشابه ل:

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

لكن هذا فشل إذا أردت إضافة وإعادة حقل آخر من tblproducties (alttext على سبيل المثال)

لقد قمت بإعداد كمان في http://sqlfiddle.com/# !2/883c5/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

نصائح أخرى

تحتاج إلى استخدام التجميع (على وجه التحديد 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

لهذا المخرج الدقيق ، قد تحتاج إلى تعديل عبارة إدراج لجدول TblProductisages على النحو التالي:

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

واستخدم عبارة SELESE أدناه:

SELECT tP.intProductID, tp.strProductName, tPI.strImageName
FROM tblProducts AS tP 
INNER JOIN tblProductImages AS tPI ON tP.intProductID = tPI.intProductID;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top