Đây là một trường hợp của phép chia quan hệ:
SELECT c.id, c.name
FROM components_componentproperty cp1
JOIN components_componentproperty cp2 USING (component_id)
JOIN components_component c ON c.id = cp1.component_id
WHERE cp1.property_id = 9102 AND cp1.value IN ('4015', '4016')
AND cp2.property_id = 8801 AND cp2.value = '3'
AND c.type_id = 3832
GROUP BY c.id;
Chúng tôi đã tập hợp một kho các kỹ thuật có liên quan tại đây:
Kiểm tra một số lượng lớn thuộc tính
Bạn có thể mở rộng truy vấn ở trên và với đầy đủ các thuộc tính, nó sẽ là một trong những giải pháp nhanh nhất có thể. Đối với một số lượng lớn hơn, sẽ thuận tiện hơn (và cũng bắt đầu nhanh hơn) để đi theo tuyến đường này:
Ví dụ cho 5 thuộc tính, hãy mở rộng khi cần thiết:
SELECT c.id, c.name
FROM (
SELECT id
FROM (
SELECT component_id AS id, property_id -- alias id just to shorten syntax
FROM components_componentproperty
WHERE property_id IN (9102, 8801, 1234, 5678, 9876) -- expand as needed
GROUP BY 1,2
) cp1
GROUP BY 1
HAVING count(*) = 5 -- match IN expression
) cp2
JOIN components_component c USING (id);
Bước bổ sung của truy vấn con bên trong cp1
chỉ cần thiết vì rõ ràng bạn có nhiều mục nhập cho mỗi (component_id, property_id)
trong components_componentproperty
. Chúng tôi có thể gấp cp1
và cp2
thành một và kiểm tra
HAVING count(DISTINCT property_id) = 5
Nhưng tôi cho rằng điều đó sẽ đắt hơn, vì count(DISTINCT col)
cần một thao tác sắp xếp mỗi hàng .
Đối với danh sách rất dài IN
là một sự lựa chọn không tồi. Cân nhắc: