Reputation: 988
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
[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
what I am trying to do is get all of the certificates that a particular student is not a part of. For example, [email protected] 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!!
Upvotes: 5
Views: 1273
Reputation: 1115
SELECT Certificate FROM `CertReqs`
WHERE Certificate NOT in(
SELECT Certificate
FROM `StudentCerts`
WHERE Email = '[email protected]'
)
Upvotes: 0
Reputation: 1
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
Upvotes: 0
Reputation: 173662
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 = '[email protected]'
WHERE sc.Email IS NULL
Upvotes: 1
Reputation: 263933
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 = '[email protected]'
ORDER BY x.EMAIL
Upvotes: 0
Reputation: 37673
SELECT cr.Certificate FROM CertReqs cr
WHERE cr.Certificate NOT IN (
SELECT sc.Certificate FROM StudentCerts sc
WHERE sc.Email = '[email protected]'
);
The query pretty much reads as the requirement: "I want all CertReqs, for which the student is NOT IN".
Upvotes: 2