2012-06-04 16 views
8

Quindi ho tre tabelle che sono coinvolte nel mio problema, 2 tabelle regolari e una tabella di join per una ha molte e appartiene a molte relazioni. Sembrano questo:Query SQL per tabella join e più valori

table1 
--id 
--data 

table2 
--id 
--data 

table1_table2 
--table1_id 
--table2_id 

Quindi, la mia domanda è: come faccio a interrogare (utilizzando un join) per qualcosa che avrebbe uno o più valori nel table1_table2 per un elemento in tabella 1. Per esempio:

Table 1 
+----------+ 
|id | data | 
+----------+ 
|1 | none | 
+----------+ 
|4 | match| 
+----------+ 

Table 2 
+----------+ 
|id | data | 
+----------+ 
|1 | one | 
+----------+ 
|2 | two | 
+----------+ 

table1_table2 
+----------------------+ 
|table1_id | table2_id | 
+----------------------+ 
|1   | 1   | 
+----------------------+ 
|4   | 1   | 
+----------------------+ 
|4   | 2   | 
+----------------------+ 

Ho bisogno di una query che sarebbe partita Tabella 1 fila id 4 perché ha un link via il join sia riga 1 e 2 dalla tabella 2. Se questo è fonte di confusione si prega di chiedere qualsiasi cosa.

Forse ero un po 'poco chiaro, sto usando table1_table2 come join non come da. Ho bisogno di assicurarsi che corrisponda 1 e 2 sia da tavolo 2.

Ecco la mia domanda finora ...

SELECT DISTINCT table1.id, 
table2.data 

FROM table1 

LEFT JOIN table1_table2 ON table1.id = table1_table2.table1_id 
LEFT JOIN table2 ON table2.id = table1_table2.table2_id 

Ho bisogno di un dove che farà che per una voce nella tabella 1 si corrisponde sia 1 e 2 da tavolo 2.

L'uscita Cerco sarebbe:

+---------------------+ 
|table1.id|table2.data| 
+---------------------+ 
|4  |one  | 
+---------------------+ 
|4  |two  | 
+---------------------+ 
+0

Stai imparando SQL (cioè sono questi compiti?) Questa è una domanda di follow-up molto ovvia a una delle tue domande precedenti (http://stackoverflow.com/questions/10726322/sql-join-using-a-join -table-da-rails). Non ho problemi con te che stai imparando su SO, ma potresti voler taggare la tua domanda [compiti a casa] se lo è. – Tony

+0

Questo non è per la scuola. – Red

+0

Sebbene la domanda sia correlata a una domanda precedente, in realtà non utilizza le stesse tabelle. Sto cambiando il nome ai tavoli che sto effettivamente usando. – Red

risposta

4

Il seguente approccio funziona se è possibile garantire che non vi siano duplicati nella tabella Table1_Table2. Forse puoi iniziare da qui e affinare un po '. Nota come funziona la condizione JOIN - mettere la IN nella condizione di join funziona in modo diverso rispetto a quando inserisci la condizione IN nella clausola WHERE.

Ho usato i segni di hash per i valori che è necessario inserire il codice nell'SQL.

SELECT Table1.id, COUNT(Table1_Table2.Table2_id) 
FROM Table1 
JOIN Table1_Table2 ON (Table1_Table2.Table1_id = Table1.id 
        AND Table1_Table2.Table2_id IN (#somelist#)) 
GROUP BY Table1.id 
HAVING COUNT(Table1_Table2.Table2_id) = (#length of somelist#) 

Oops: hai cambiato la domanda nel modo che ho suggerito e ho ignorato la tua modifica. Ma questo dovrebbe iniziare, poiché restituisce tutti gli id ​​Table1 a cui sei interessato.

0

penso che si dovrebbe essere in grado di selezionare questo:

select table1_id, count(*) as count from table1_table2 group by table1_id having count > 2; 

gruppo per, contare e avere i tuoi amici!

+0

Forse ero un po 'confuso, sto usando table1_table2 come join non come da. Devo assicurarmi che corrisponda a 1 e 2 entrambi. Cambierò la domanda per riflettere questo. – Red

2

Ecco la mia soluzione. Non è molto generalizzato. Dovresti pubblicare un commento se questa soluzione non funziona perché è troppo specifica per la tua situazione.

SELECT DISTINCT Table1.id 
FROM Table1 
INNER JOIN table1_table2 a ON (table1.id = table1_table2.table1_id 
          AND table2.id = 1) 
INNER JOIN table1_table2 b ON (table1.id = table1_table2.table1_id 
          AND table2.id = 2) 
+1

Credo che funzionerebbe, l'unico problema è che a volte posso avere più di due valori, a volte potrei avere fino a 50 valori. Che molti join diventerebbero piuttosto difficili sul DB e renderli dinamici diventerebbero difficili. – Red

+0

Quindi vuoi la lista di tutti gli id ​​di table1 che corrispondono a OGNI tabella2, indipendentemente da quante cose ci sono in table2? –

+0

Beh, non tutto nella tabella 2, ma almeno quello che ho detto. Nell'esempio volevo solo l'elenco delle voci della tabella 1 corrispondenti a 1 e 2. Potrei tuttavia (se esistessero) una query che ottenga tutte le voci della tabella 1 che corrispondono a 1, 2, 3 e 7 della tabella 2 Devo assicurarmi che corrisponda a tutti loro. – Red

1

Se dovessi farlo in SQL Server, inserirò i valori che desideri controllare in una tabella temporanea (o variabile di tabella) e quindi utilizzare una variazione di ciò che @ChrisCunningham ha detto.

CREATE TABLE #temp (Id INT) 
INSERT INTO #temp 
VALUES (1, 3, 7) 

SELECT a.id AS table1ID, table2.data 
FROM 
(
     SELECT Table1.id, Table1_Table2.table2_id 
    FROM Table1 JOIN Table1_Table2 
     ON (Table1_Table2.Table1_id = Table1.id      
    AND Table1_Table2.Table2_id IN (SELECT Id FROM #temp)) 
    GROUP BY Table1.id 
    HAVING COUNT(Table1_Table2.Table2_id) = (SELECT count (*) FROM #temp) 
    ) a 
JOIN Table2 ON Table2.id = a.Table2_id 

Naturalmente io non sono sicuro di quali meccanismi Postgre ha per tabelle temporanee, ma si dovrebbe anche fare una stored procedure in cui si utilizza una sorta di funzione split per creare i valori per la tabella temporanea piuttosto che la come l'ho fatto io Ma almeno questo potrebbe darti un'idea.