2012-11-12 9 views
7

Voglio interrogare una tabella di giunzione per il valore della colonna aID che corrisponde a tutti i valori di un elenco di ID ids=[3,5] nella colonna bID.SqlAlchemy: filtro per corrispondere a tutti anziché a qualsiasi valore nell'elenco?

Questa è la mia tabella di collegamento (JT):

aID bID 
    1  1 
    1  2 
    2  5 
    2  3 
    1  3 
    3  5 

ho questa query: session.query(JT.aID).filter(JT.bID.in_(ids)).all()

Questa query restituisce i aID valori 1, 2 e 3 perché tutti hanno le righe con uno 3 o 5 nella colonna bID. Quello che voglio che la query restituisca è 2 perché quello è l'unico valore aID che contiene tutti i valori dell'elenco ids nella colonna bID.

Non so come spiegare meglio il problema, ma come posso ottenere il risultato?

+1

avrei forse scambiare uno dei tuoi tag per il generico 'tag sql', perché questo è in realtà un generico problema query SQL e in questo modo potrai migliorare la visibilità della tua domanda. –

risposta

3

Si sta cercando una query che funzioni su gruppi di righe. Credo che un gruppo di avere clausola è l'approccio migliore:

select aid 
from jt 
where bid in (<your list>) 
group by aid 
having count(distinct bid) = 2 

Se si può mettere gli ID che desiderate in una tabella, si può fare il seguente approccio più generico:

select aid 
from jt join 
    bids 
    on jf.bid = bids.bid 
group by aid 
having count(distinct jt.bid) = (select count(*) from bids) 
+0

SqlAlchemy ha una sintassi specifica per questo o deve essere in SQL? – boadescriptor

+0

SQLAlchemy è in grado di produrre query come queste con il suo linguaggio di espressione SQL, abbastanza ben trattato nei suoi documenti, anche se potresti aver bisogno di sperimentare un po 'con la sintassi Python prima di ottenerlo. In alternativa, sqlalchemy consente anche di inviare query dirette come valori letterali di testo. Infine, se hai una reale necessità di costruire la query dinamicamente, assemblandola dalle parti dei componenti in base a ciò che accade nella logica del tuo programma, puoi procedere con gli strumenti ORM di sqlalchemy, ma normalmente non lo sceglierai più a lungo e più lentamente metodo a meno che non fosse veramente necessario. – cdaddr

0

Try :

session.query(JT.aID).filter(not_(JT.bID.in_(ids))).all() 
9

sulla base @Gordon Linoff risposta e con due tavoli A e B dove A ha una relazione one a uomo y verso B chiamato A.bs l'equivalente SQLAlchemy sarebbe:

from sqlalchemy import func 
session.query(A).join(B).filter(B.id.in_(<your_list>)).group_by(A.id).having(func.count(A.bs) == len(<your_list>)).all() 
Problemi correlati