2013-06-12 17 views
5

Sto eseguendo una query che contiene stessa sottoquestione utilizzata più volte in una clausola WHERE.Stessa query secondaria utilizzata più volte in una singola query

Ho un tavolo con campi di traino client_id, buyer_id.

La sottoquery restituisce l'elenco di date da escludere dal risultato.

Ecco come lo sto usando.

SELECT 
    id, client_id, buyer_id 
FROM relation 
WHERE 
    client_id NOT IN (SELECT <some_id> FROM <some_table> WHERE ...) 
    AND buyer_id NOT IN (SELECT <some_ids> FROM <some_table> WHERE ...) 

Questo funziona come previsto, ma quello che mi preoccupa che ci sono due stessi sub-query. Mi chiedo se c'è un modo in cui posso usarlo una volta e usare il risultato per entrambi i posti.

Grazie.

+0

Hai provato sostituendo che subquery con un JOIN? – Taryn

+0

@bluefeet, ho semplificato questa query in un modo lungo solo per darti il ​​vero problema. Inoltre non sono in grado di capire come sarebbe la clausola 'ON 'di' JOIN'. –

risposta

3

È possibile scrivere questo utilizzando NOT EXISTS:

SELECT 
    id, client_id, buyer_id 
FROM relation AS r 
WHERE NOT EXISTS 
     (SELECT 1 
     FROM <some_table> 
     WHERE (r.client_id = <some_id> OR r.buyer_id = <some_id>) 
      AND ... 
    ) ; 
+0

Ricevo l'eccezione "Errore correlazione campo" in una query simile. – serdar

1

query della forma:

select ... 
from <main query> 
where <select field> not in (select <subquery field> from <subquery>) 

può normalmente essere riformulato come:

select <main query fields> 
from <main query> 
left join <subquery> on <select field> = <subquery field> 
where <subquery field> is null 

Se il sub-query che si sta utilizzando è esattamente lo stesso sia per client_id e buyer_id, si dovrebbe pertanto essere possibile riformulare la query come:

SELECT id, client_id, buyer_id 
FROM relation 
LEFT JOIN <some_table> ON <some_id> IN (client_id, buyer_id) 
WHERE <some_id> IS NULL 

- utilizza quindi efficacemente la sottoquery solo una volta nella query.

+0

Una soluzione con un join potrebbe non restituire lo stesso risultato di una soluzione con una sottoquery. –

+0

Esattamente quello che sto vivendo. Non sta restituendo la stessa riga, piuttosto più righe. Anche prendendo più tempo pure. La mia query originale è in esecuzione in 41 secondi e quando l'ho usata in JOIN ci sono voluti 61 secondi. –

+1

@TalhaAhmedKhan Puoi fornire un [SQL-Fiddle] (http://sqlfiddle.com/) con alcuni dati? Penso che questa query sia equivalente a ciò che hai (se le colonne 'client_id' e' buyer_id' non sono annullabili.) –

0

Vostri criteri potrebbe essere trasformato nel seguente modo:

SELECT 
    id, client_id, buyer_id 
FROM relation 
LEFT JOIN some_table 
) AS subquery ON (subquery.some_id IN (client_id, buyer_id) AND <condition that was in your subquery>) 
WHERE subquery.some_id IS NULL; 

ma ho la sensazione che questo sarà ancora eseguire molto male in termini di tempo di esecuzione.

Considera la possibilità di creare una tabella temporanea contenente i contenuti della sottoquery.

0

Sarebbe di aiuto provare a inserire i valori recuperati in una tabella di database separata, in modo che sia possibile stabilire se esistono valori di risultato simili o diversi quando si hanno già risultati in una tabella separata. In attesa di sentire il tuo giudizio ... Buona fortuna, per favore.

Problemi correlati