2013-05-24 17 views
11

Ho una tabella in MySQL come segue.Query SQL per la corrispondenza di più valori nella stessa colonna

Id Designation   Years   Employee 
1 Soft.Egr   2000-2005   A 
2 Soft.Egr   2000-2005   B 
3 Soft.Egr   2000-2005   C 
4 Sr.Soft.Egr   2005-2010   A 
5 Sr.Soft.Egr   2005-2010   B 
6 Pro.Mgr    2010-2012   A 

ho bisogno di ottenere i dipendenti che hanno lavorato come Soft.Egr e Sr.Soft.Egr e Pro.Mgr. Non è possibile utilizzare IN o più AND nella query. Come fare questo??

+0

È necessario utilizzare 'self join' per ottenere il risultato desiderato. Consulta http://www.tutorialspoint.com/sql/sql-self-joins.htm – Meherzad

risposta

6

Cosa si potrebbe effettivamente essere alla ricerca di è relational division, anche se i requisiti di esercizio proibiscono usando AND (per qualsiasi motivo?). Questo è difficile, ma è possibile esprimere correttamente in SQL.

La divisione relazionale in prosa significa: Trova quei dipendenti che hanno un record nella tabella dei dipendenti per tutte le designazioni esistenti. O in SQL:

SELECT DISTINCT E1.Employee FROM Employees E1 
WHERE NOT EXISTS (
    SELECT 1 FROM Employees E2 
    WHERE NOT EXISTS (
     SELECT 1 FROM Employees E3 
     WHERE E3.Employee = E1.Employee 
     AND E3.Designation = E2.Designation 
    ) 
) 

Per vedere la query di cui sopra in azione, considerano questo SQLFiddle

Una buona risorsa che spiega divisione relazionale può essere trovato qui: http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division

+0

non sappiamo per certo che queste siano tutte le possibili designazioni, queste sono solo quelle nell'esempio - soluzione interessante comunque! – ninesided

+1

@nineided: lo so, probabilmente hai ragione. Ma ho una sensazione istintiva (dal momento che questa è una domanda accademica), che questo potrebbe riguardare la divisione relazionale. E se non lo è, è comunque bene aumentare la consapevolezza della divisione relazionale su Stack Overflow :-) –

19

Un modo:

select Employee 
from job_history 
where Designation in ('Soft.Egr','Sr.Soft.Egr','Pro.Mgr') 
group by Employee 
having count(distinct Designation) = 3 
3

Se avete bisogno di ottenere ulteriori informazioni relativamente a ciascuno dei ruoli (come le date) poi unirsi di nuovo al vostro tavolo originale per ciascuna delle designazioni supplementari è una possibile soluzione:

SELECT t.Employee, t.Designation, t.Years, t1.Designation, t1.Years, t2.Designation, t2.Years 
FROM Table t 
INNER JOIN t2 ON (t2.Employee = t.Employee AND t2.Designation = 'Sr.Soft.Egr') 
INNER JOIN t3 ON (t3.Employee = t.Employee AND t3.Designation = 'Soft.Egr') 
WHERE t.Designation = 'Pro.Mgr'; 
1

Perché non la seguente (per PostgreSQL)?

SELECT employee FROM Employees WHERE Designation ='Sr.Soft.Egr' 
INTERSECT 
SELECT employee FROM Employees WHERE Designation ='Soft.Egr' 
INTERSECT 
SELECT employee FROM Employees WHERE Designation ='Pro.Mgr' 

Link SQLfiddle

So che questo potrebbe non ottimizzato, ma trovo questo molto più facile da comprendere e modificare.

Problemi correlati