2012-12-07 23 views
5

電子メール(主キー)と証明書を含むStudentCertsと、証明書とコースを含むCertReqsという2つのテーブルがあります。テーブルの一部のようななります:私が何をしようとしています何トリッキーなSQL結合クエリ

 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 

は、特定の学生がの一部ではないすべての証明書を取得することです。例えば、[email protected]はProgrammerとEnglishの両方の証明書に登録されています。そして、特定の生徒が登録されていないCertReqのすべての証明書を私に返すSQLステートメントを取得したいと思います。 Econ、Art、Journalismを返すべきです。 私はしばらくこれを得るのに苦労していたので、どんな助けでも大いに感謝されるでしょう!

答えて

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

質問は、「学生が入院していないすべてのCertReqを欲しい」という要件とほぼ同じです。

+0

はどうもありがとうございました!これはまさに私がやろうとしていたことでした! – user1875195

0

これは、あなたが特定の電子メールのために必要ならば、あなただけの余分な状態に

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 
を追加する必要がある特定の証明書の

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 

を欠いている、すべての学生が一覧表示されます

0
SELECT Certificate FROM `CertReqs` 

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

ゲームでは少し遅れますが、簡単なLEFT JOINは非常によく、この問題を解決:

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

ようこそスタックオーバーフロー!このコードスニペットは問題を解決するかもしれませんが、[説明を含めて](// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)本当にあなたの投稿の質を向上させるのに役立ちます。将来読者の質問に答えていることを覚えておいてください。そうした人々はあなたのコード提案の理由を知らないかもしれません。あなたのコードに説明的なコメントを詰め込まないようにしてください。これは、コードと説明の両方の可読性を低下させます! – Machavity