简体   繁体   中英

MySQL find rows not in other table

I am a bit stunned that I am no able to produce my results I want to get so I ask you experts for help!

I have three Tables showing only the important parts:

T1: (List of all names and schedules assigned)
Name | ScheduleName

T2: (all possible schedule names)
ScheduleName

T3: (List of all names)
Name

I try to find the ScheduleName per Person that was not assigned. In the end I would like to see:

Name1 | ScheduleName1 
Name1 | ScheduleName2
Name1 | ScheduleName3
Name2 | ScheduleName2

What I tried:

SELECT
    T2.ScheduleName
FROM
    T2
WHERE
    T2.ScheduleName NOT IN
(SELECT T1.ScheduleName FROM T1 WHERE T1.Name = "Name1")

This gives me the not assigned schedules for Person Name1. Works.
If I remove the WHERE statement within the parenthesis it returns no rows. (Because it matches it against the whole dataset)

Help very much appreciated

Thanks in advance

EDIT: Tried to work with a LEFT JOIN but it is not returning rows with "NULL" although it should

Here is one option, using a cross join:

SELECT
    T3.Name,
    T2.ScheduleName
FROM T2
CROSS JOIN T3
LEFT JOIN T1
    ON T2.ScheduleName = T1.ScheduleName AND T3.Name = T1.Name
WHERE
    T1.Name IS NULL;

The idea behind the cross join is that it generates all possible pairings of names and schedules. That is, it represents the entire set of all pairings. Then, we left join this to the T1 assignment table to find pairings which were never made.

We could also have achieved the same thing using EXISTS logic:

SELECT
    T3.Name,
    T2.ScheduleName
FROM T2
CROSS JOIN T3
WHERE NOT EXISTS (SELECT 1 FROM T1
                  WHERE T2.ScheduleName = T1.ScheduleName AND T3.Name = T1.Name);

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