I have a complex domain structure:
User: id, name, email
Team: id, name
UserTeam: id, user_id, team_id
Session: id, data
UserSession: id, user_id, session_id
TeamSession: id, team_id, session_id
Scan: id, user_id, session_id, test_data
I can invite users to take a “session”. A user can take a session (one UserSession is made) and if completed, the result is stored in a Scan. I can also invite a complete team, so one TeamSession is created and for every team member, a UserSession is made.
Now I want to perform the query: give me all the scans not yet performed (so I can remember users to take one). For this case, I want to select all usersessions and join scans where the scan id is NULL. I thought this was the way to find out a row from a joining table is not present yet.
This was my query:
SELECT us.id as userSessionId,
sc.id as scanId,
s.id as sessionId,
u.id, u.name
FROM usersessions us
LEFT JOIN sessions s ON us.session_id = s.id
LEFT JOIN scans sc ON us.session_id = sc.session_id
LEFT JOIN users u ON us.user_id = u.id
WHERE sc.id IS NULL
GROUP BY us.id
However, it does not work: nothing is returned while at least one user has not performed a scan yet. If I remove the WHERE clause to see what the data is, I get this back:
userSessionId scanId sessionId id name
45 45 39 39 John
46 45 39 40 Jane
47 45 39 41 Tom
48 45 39 42 Mark
In this case, all are in the same group and got a session (#39). Their user ids and user session ids are correct. Mark has not performed a scan. John did scan #45 (for Jane it was #46 and Tom #47).
If I add a where clause WHERE sc.user_id=u.id, I get the correct three results (scans #45, #46 and #47) but then Mark is missing. That’s the only one I want to grab in the end! If you change it then to both clauses WHERE sc.user_id=u.id AND sc.id IS NULL it (obviously now) returns nothing again.
What’s the query to get all user sessions NOT connected to a scan?
You can try this solution. If it works for you, I will edit my post to add an explanation:
I’m assuming your data looks something like this:
In which case you should end up with:
Let me know if your scans table is allowed to look something like:
^ In which case my query would not work, and would need to be rewritten (and I know how).