Pregunta

Tengo tres tablas en el formato de muchos a muchos. Es decir, las tablas A, B y AB configuradas como es de esperar.

Dado un conjunto de identificadores A, necesito seleccionar solo las filas en AB que coinciden con todos los identificadores.

Algo como lo siguiente no funcionará:

" SELECCIONAR * DE AB DONDE A_id = 1 AND A_id = 2 AND A_id = 3 AND ... " Como ninguna fila tendrá más de un A_id

Usando, un OR en el estado de SQL no es mejor ya que produce resultados de todos los resultados que tienen al menos uno de los identificadores A (mientras que solo quiero esas filas que tienen todos los identificadores).

Edición :

Lo siento, debería explicarlo. No sé si la relación real de muchos a muchos es relevante para el problema real. Las tablas se resumen de la siguiente manera:

Table People
int id
char name

Table Options
int id
char option

Table peoples_options
int id
int people_id
int option_id

Y entonces tengo una lista de personas, y una lista de opciones, y una tabla de opciones y personas.

Entonces, dada una lista de identificadores de opciones como (1, 34, 44, ...), necesito seleccionar solo aquellas personas que tienen todas las opciones.

¿Fue útil?

Solución

Un poco de una solución hacky es utilizar IN con un grupo y con filtro. Me gusta así:

SELECT B_id FROM AB
WHERE A_id IN (1,2,3)
GROUP BY B_id
HAVING COUNT(DISTINCT A_id) = 3;

De esa manera, solo obtienes los valores B_id que tienen exactamente 3 valores A_id, y tienen que ser de tu lista. Usé DISTINCT en COUNT por si acaso (A_id, B_id) no es único. Si necesita otras columnas, puede unirse a esta consulta como una subselección en la cláusula FROM de otra instrucción select.

Otros consejos

Su base de datos no parece estar normalizada correctamente. Su tabla AB debe tener un solo A_id y un solo B_id en cada una de sus filas. Si ese fuera el caso, su versión OR debería funcionar (aunque yo mismo usaría IN ).

Ignora el párrafo anterior. Desde su edición, realmente quería saber todos los B que tienen todo un subconjunto de A en la tabla de varios a varios. la consulta.

Por favor díganos los detalles del esquema real, es un poco difícil descubrir qué quiere sin eso.

Esperaría ver algo como:

table a:
    a_id integer
    a_payload varchar(20)
table b:
    b_id integer
    b_payload varchar(20)
table ab:
    a_id integer
    b_id integer

Según su descripción, lo único en lo que puedo pensar es que desea una lista de todos los B que tienen todo un conjunto de A ' s en la tabla AB . En ese caso, está buscando algo como (para obtener la lista de B que tienen A 's de 1, 3 y 4):

select distinct b_id from ab n1             
    where exists (select b_id from ab where a_id = 1 and b_id = n1.b_id)     
    and   exists (select b_id from ab where a_id = 3 and b_id = n1.b_id)     
    and   exists (select b_id from ab where a_id = 4 and b_id = n1.b_id);    

Esto funciona en DB2 pero no estoy seguro de cuánto SQL implementa el servidor elegido.

Pruebe esto ... Trae a todas las personas asociadas con todas las opciones.

En otras palabras, la consulta trae a todas las personas que no existe una opción que no estaba asociada a ella.


select
    p.*
from
    people p
where
    not exists (
              select 
                      1 
              from 
                      options o
              where
                      not exists 
                      (
                          select 1
                          from   peoples_options po 
                          where  po.people_id     = p.people_id
                                 AND po.option_id = o.option_id
                      )
           )
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top