2012-12-07 18 views
5

Mam dwie tabele, jedna nazywa StudentCerts zawierający e-mail (klucz podstawowy) i certyfikat, a drugi o nazwie CertReqs, zawierający certyfikat i oczywiście. Część tabeli może wyglądać w następujący sposób:Tricky SQL Dołącz zapytanie

 StudentCerts:         CertReqs:  
Email   Certificate    Certificate   Course 
[email protected]  Programmer   Programmer   CS 101 
[email protected]  English    Programmer   CS 202 
[email protected]   Econ     Programmer   CS 303 
[email protected]  Programmer   English    ENG 101 
             English    ENG 102 
             Econ     ECON 102 
             Econ     ECON 304 
             Art     Art 101 
             Art     Art 102 
             Journalism   J 101 
             Journalism   J 202 

co próbuję zrobić, to wszystkie certyfikaty, że dany uczeń nie jest częścią. Na przykład [email protected] jest zapisany w certyfikacie Programmer i angielskim, I chciałbym otrzymać instrukcję SQL, która zwróci mi wszystkie certyfikaty w CertReqs, do których dany student nie jest zapisany. Tak więc w tym przykładzie powinien powrócić Econ, Art i Journalism. Starałem się to zdobyć przez jakiś czas, więc każda pomoc byłaby bardzo ceniona !!

Odpowiedz

2
SELECT cr.Certificate FROM CertReqs cr 
WHERE cr.Certificate NOT IN (
    SELECT sc.Certificate FROM StudentCerts sc 
    WHERE sc.Email = '[email protected]' 
); 

Zapytanie dość często brzmi: "chcę wszystkie certyfikaty, dla których uczeń NIE JEST".

+0

Dziękuję bardzo! To właśnie zrobiłem, co starałem się zrobić! – user1875195

0

To listę wszystkich studentów brakuje do pewnego świadectwa

SELECT DISTINCT x.* 
FROM 
    (
     SELECT a.Email, b.Certificate 
     FROM (SELECT DISTINCT Email FROM StudentCerts) a 
       CROSS JOIN 
       (SELECT DISTINCT Certificate FROM CertReqs) b 
    ) x LEFT JOIN studentCerts y 
     ON x.Email = y.Email AND 
      x.Certificate = y.Certificate 
WHERE y.Email IS NULL 
ORDER BY x.EMAIL 

jeśli chcesz dla konkretnego email potem tylko trzeba dodać dodatkowe warunek

SELECT DISTINCT x.* 
FROM 
    (
     SELECT a.Email, b.Certificate 
     FROM (SELECT DISTINCT Email FROM StudentCerts) a 
       CROSS JOIN 
       (SELECT DISTINCT Certificate FROM CertReqs) b 
    ) x LEFT JOIN studentCerts y 
     ON x.Email = y.Email AND 
      x.Certificate = y.Certificate 
WHERE y.Email IS NULL AND 
     x.Email = '[email protected]' 
ORDER BY x.EMAIL 
0
SELECT Certificate FROM `CertReqs` 

WHERE Certificate NOT in(
    SELECT Certificate 
    FROM `StudentCerts` 
    WHERE Email = '[email protected]' 
) 
1

Trochę późno w grze, ale prosty LEFT JOIN rozwiązuje ten problem dość dobrze:

SELECT DISTINCT cr.Certificate 
FROM CertReqs cr 
LEFT JOIN StudentCerts sc ON cr.Certificate = sc.Certificate AND sc.Email = '[email protected]' 
WHERE sc.Email IS NULL 
0
SELECT DISTINCT A.* fROM 
(
SELECT DISTINCT EMAIL, CERTIFICATE fROM #StudentCerts A 
CROSS JOIN #CertReqs B) A 
LEFT JOIN #StudentCerts B ON A.EmaiL = B.EMAIL AND B.CERTIFICATES = A.Certificate 
WHERE B.EMAIL IS NULL 
ORDER BY A.EMAIL 
+2

Witamy w Stack Overflow! Chociaż ten fragment kodu może rozwiązać pytanie, [w tym wyjaśnienie] (// meta.stackexchange.com/questions/114762/explaining-entirely-code-ans -answers) naprawdę pomaga poprawić jakość twojego posta. Pamiętaj, że odpowiadasz na pytanie przeznaczone dla czytelników w przyszłości, a te osoby mogą nie znać powodów sugestii dotyczących kodu. Proszę również starać się nie tłumić kodu za pomocą komentarzy wyjaśniających, co zmniejsza czytelność zarówno kodu, jak i objaśnień! – Machavity