sql >> Database >  >> RDS >> PostgreSQL

Haal meerdere rijen op met een query met AND en OR

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:




  1. Mysql2 gem installeren op Mac os x Lion

  2. Controleer of er al een door de gebruiker gedefinieerd type bestaat in PostgreSQL

  3. Hoe meerdere rijen uit de opgeslagen procedure te retourneren? (Oracle PL/SQL)

  4. Kan een MySQL-tabel niet DROPEN