简体   繁体   中英

Tricky SQL Join Query

I have two tables, One called StudentCerts containing an email (the primary key) and a certificate, and another called CertReqs, containing a Certificate and Course. Part of the table could look as such:

     StudentCerts:                                 CertReqs:    
Email           Certificate             Certificate          Course
This@that.com      Programmer            Programmer           CS 101
This@that.com      English               Programmer           CS 202
A@B.com            Econ                  Programmer           CS 303
john@smith.com     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

what I am trying to do is get all of the certificates that a particular student is not a part of. For example, This@that.com is enrolled in both the Programmer and English certificate, And I would like to get an SQL statement that would return me all of the certificates in CertReqs that the particular student is not enrolled in. So for this example it should return Econ, Art, and Journalism. Ive been struggling to get this for some time, so any help would be greatly appreciated!!

SELECT cr.Certificate FROM CertReqs cr
WHERE cr.Certificate NOT IN (
    SELECT sc.Certificate FROM StudentCerts sc
    WHERE sc.Email = 'This@that.com'
);

The query pretty much reads as the requirement: "I want all CertReqs, for which the student is NOT IN".

A little late in the game, but a simple LEFT JOIN solves this problem quite well:

SELECT DISTINCT cr.Certificate 
FROM CertReqs cr
LEFT JOIN StudentCerts sc ON cr.Certificate = sc.Certificate AND sc.Email = 'This@that.com'
WHERE sc.Email IS NULL

This will list all student lacking for a certain certificate

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

if you want for specific email then you only need to add extra condition

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 = 'This@that.com'
ORDER BY x.EMAIL
SELECT Certificate FROM `CertReqs` 

WHERE Certificate NOT in(
    SELECT Certificate 
    FROM `StudentCerts` 
    WHERE Email  = 'This@that.com' 
)
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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM