2011-12-08 10 views
24

Ok, quindi ho una tabella temporanea che contiene userID e taskID. Si chiama CompletedTasks. Ho una seconda tabella che contiene userID e taskID. Si chiama PlannedTasks.mysql "Dove non ci sono" utilizzando due colonne

Ho bisogno di ottenere un elenco di tutti gli taskID completati, ma non pianificati. Quindi, ho bisogno di estirpare in qualche modo dalle attività completate tutte le righe dove sia PlannedTasks.userID != CompletedTasks.userID AND PlannedTasks.taskID != CompletedTasks.taskID.

Spero che questa domanda abbia senso. Per favore fatemi sapere se non è chiaro e spiegherò ulteriormente.

Grazie per eventuali suggerimenti!

+0

Penso che sia necessaria una colonna aggiuntiva per indicare lo stato, in realtà non servono due tabelle. – ajreal

+0

@ajreal Questo è un buon punto. Forse prenderò in considerazione la possibilità di modificare lo schema nel modo suggerito. Apprezzo il suggerimento! – PFranchise

+1

Preferisco 2 tabelle su una tabella e una colonna di stato, il 99% delle volte. E 11 tabelle su una tabella e 10 colonne di stato. Non è facile ottimizzare una query che ricerca una o più colonne di stato (in MysQL). –

risposta

62

È possibile utilizzare questo (più la sintassi compatta):

SELECT * 
FROM CompletedTasks 
WHERE (userID, taskID) NOT IN 
     (SELECT userID, taskID 
     FROM PlannedTasks 
    ) ; 

o la versione NOT EXISTS (che anche se più complesso, dovrebbe essere più efficiente con gli indici corretti):

SELECT c.* 
FROM CompletedTasks AS c 
WHERE NOT EXISTS 
     (SELECT 1 
     FROM PlannedTasks AS p 
     WHERE p.userID = c.userID 
      AND p.taskID = c.taskID 
    ) ; 

e, naturalmente, la versione LEFT JOIN/IS NULL che @jmacinnes ha nella sua risposta.

+0

Fantastico! Grazie mille. Non sapevo che si potesse usare Where su due campi in quel modo, ma speravo che sarebbe stata un'opzione. grazie ancora e buona giornata! – PFranchise

+0

Dopo i miei test, la versione NOT EXISTS è più veloce della versione NOT_IN –

+0

@Ka. sì, il 'NOT IN' con una tupla non è ottimizzato come' NOT EXISTS'. Con quale versione hai provato? Non ho testato se hanno migliorato l'ottimizzatore nella nuova versione 5.7. –

5

È questo quello che ti serve?

select ct.* from 
completedTasks ct 
left outer join plannedTasks pt on ct.taskId = pt.TaskId and ct.userId = pt.userId 
where pt.taskId is null 

Tuttavia, sono d'accordo con il commento - dato quello che sappiamo dalla questione di una colonna di stato suona come uno schema meglio di due tabelle.

0

@ ypercubeᵀᴹ Grazie per la condivisione di sotto di query menzione

SELECT * FROM CompletedTasks WHERE (userID, taskID) NOT IN 
     (SELECT userID, taskID FROM PlannedTasks) ;' 

Il mio problema risolto.

+0

Questo dovrebbe essere un commento, non una risposta :) – sniperd

+0

In realtà, ho apportato alcune modifiche con riferimento alla query condivisa @ypercube. Si prenderà cura in futuro. Grazie –

Problemi correlati