2012-12-07 16 views
5

İki tablo var: Biri e-posta (birincil anahtar) ve bir sertifika içeren bir StudentCerts ve bir Sertifika ve Kurs içeren bir başka CertReqs adında. Tablonun Bölüm gibi görünebilir: Yapmak ne çalışıyorumTricky SQL Katılma Sorgusu

 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 

belirli öğrenci bir parçası değildir sertifikaların tüm olsun. Örneğin, [email protected] hem Programlayıcı hem de İngilizce sertifikasına kaydolur. Ayrıca, belirli bir öğrencinin kayıtlı olmadığı CertReqs içindeki tüm sertifikaları bana iade edecek bir SQL ifadesi almak istiyorum. Bu örnek için Econ, Art ve Journalism'i geri vermeli. Bir süreliğine bunu elde etmek için uğraşıyordum, bu yüzden herhangi bir yardım büyük beğeni topladı!

cevap

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

sorgu hemen hemen gereği olarak okur: "Ben öğrenci İÇİNDE DEĞİL olduğu tüm CertReqs, istiyoruz".

+0

Çok teşekkür ederim! Bu tam olarak ne yapmaya çalıştığımı yaptı! – user1875195

0

Bu, daha sonra belirli e-posta için isterseniz

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 

sadece ekstra koşul eklemeniz gerekir belli bir sertifika için eksik tüm öğrenci listeler

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

oyunda biraz geç, ancak basit bir LEFT JOIN oldukça iyi bu sorunu çözer:

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

Yığın Taşmasına Hoş Geldiniz! Bu kod pasajı [bir açıklama dahil] [// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers] sorusunu çözebilirken, yayınınızın kalitesini artırmanıza yardımcı olur. İleride okuyucuları için soruya cevap olduğunu hatırlayın ve bu kullanıcıların da kod öneri nedenlerini bilmiyor olabilir. Lütfen kodunuzu açıklayıcı yorumlarla doldurmamaya çalışın, bu hem kodun hem de açıklamaların okunabilirliğini azaltır! – Machavity