Ini adalah kasus pembagian relasional:
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;
Kami telah mengumpulkan gudang teknik yang relevan di sini:
Periksa sejumlah besar properti
Anda dapat memperluas kueri di atas dan untuk sebagian besar properti, itu akan menjadi salah satu solusi tercepat yang mungkin. Untuk jumlah yang lebih besar akan lebih mudah (dan juga mulai lebih cepat) untuk menempuh rute ini:
Contoh untuk 5 properti, perluas sesuai kebutuhan:
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);
Langkah ekstra dari subquery dalam cp1
hanya diperlukan, karena Anda jelas memiliki banyak entri per (component_id, property_id)
di components_componentproperty
. Kami bisa lipat cp1
dan cp2
menjadi satu dan periksa
HAVING count(DISTINCT property_id) = 5
Tapi saya berharap itu lebih mahal, karena count(DISTINCT col)
membutuhkan satu operasi pengurutan per baris .
Untuk daftar yang sangat panjang IN
adalah pilihan yang buruk. Pertimbangkan: