Dit is een geval van relationele verdeling:
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;
We hebben hier een arsenaal aan relevante technieken verzameld:
Controleer op een groot aantal eigenschappen
U kunt de bovenstaande zoekopdracht uitbreiden en voor een handvol woningen is dit een van de snelst mogelijke oplossingen. Voor een groter aantal zal het handiger zijn (en ook sneller gaan) om deze route te volgen:
Voorbeeld voor 5 eigenschappen, uitbreiden indien nodig:
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);
De extra stap van de innerlijke subquery cp1
is alleen nodig, want je hebt natuurlijk meerdere vermeldingen per (component_id, property_id)
in components_componentproperty
. We kunnen vouw cp1
en cp2
in één en controleer
HAVING count(DISTINCT property_id) = 5
Maar ik verwacht dat dat duurder zal zijn, aangezien count(DISTINCT col)
heeft één sorteerbewerking nodig per rij .
Voor zeer lange lijsten IN
is een slechte keuze. Overweeg: