sql >> Base de Datos >  >> RDS >> PostgreSQL

Recupere varias filas con consulta usando AND y OR

Este es un caso de división relacional:

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;

Hemos reunido un arsenal de técnicas relevantes aquí:

Buscar un gran número de propiedades

Puede expandir la consulta anterior y, para un puñado de propiedades, estará entre las soluciones más rápidas posibles. Para un número mayor será más conveniente (y también empezará a ser más rápido) seguir esta ruta:

Ejemplo para 5 propiedades, expanda según sea necesario:

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);

El paso adicional de la subconsulta interna cp1 solo es necesario, porque obviamente tiene varias entradas por (component_id, property_id) en components_componentproperty . Nosotros podríamos doblar cp1 y cp2 en uno y comprobar

HAVING count(DISTINCT property_id) = 5

Pero espero que sea más caro, ya que count(DISTINCT col) necesita una operación de clasificación por fila .

Para listas muy largas IN es una mala elección. Considere: