Tôi sẽ viết kết hợp loại trừ mà không có truy vấn phụ:
SELECT p.productid
FROM products p
INNER JOIN producttags AS t ON p.productid = t.productid
LEFT OUTER JOIN producttags AS x ON p.productid = x.productid
AND x.tag IN ('Motorcycle', 'Green')
WHERE p.active = 1
AND t.tag IN ( 'Ford', 'Black', 'Skateboard' )
AND x.productid IS NULL;
Đảm bảo rằng bạn có chỉ mục về các sản phẩm trên hai cột (hoạt động, sản xuất) theo thứ tự đó.
Bạn cũng nên có một chỉ mục trên thẻ sản phẩm trên hai cột (sản phẩm, thẻ) theo thứ tự đó.
Một truy vấn khác mà tôi sẽ cần thực hiện là tất cả (Ô tô) hoặc (Ván trượt) hoặc (Màu xanh lá cây VÀ Xe máy) hoặc (Màu đỏ VÀ Xe máy).
Đôi khi những điều kiện phức tạp này khó đối với trình tối ưu hóa MySQL. Một giải pháp phổ biến là sử dụng UNION để kết hợp các truy vấn đơn giản hơn:
SELECT p.productid
FROM products p
INNER JOIN producttags AS t1 ON p.productid = t1.productid
WHERE p.active = 1
AND t1.tag IN ('Car', 'Skateboard')
UNION ALL
SELECT p.productid
FROM products p
INNER JOIN producttags AS t1 ON p.productid = t1.productid
INNER JOIN producttags AS t2 ON p.productid = t2.productid
WHERE p.active = 1
AND t1.tag IN ('Motorcycle')
AND t2.tag IN ('Green', 'Red');
Tái bút:Bảng gắn thẻ của bạn không phải là bảng Thực thể-Thuộc tính-Giá trị.