Overview
I'm simplifying the description of my application to make the query clearer. The application stores saved phrases
. These phrases are each assigned a category
. The phrases can be posted
by users
. An English description of my query:
I need to pass a
category
anduser
into theprepared statement
. The result will include onlyphrases
with thecategory
passed as an argument. From thephrases
of thiscategory
, onlyphrases
will be returned where there does not exist any posted instances of thisphrase
for theuser
argument with thetimePosted
field in the last two weeks.
Minimal Schema
savedPhrase
- phraseIdentifier - INT UNSIGNED
- textContent - VARCHAR
- associatedCategory - VARCHAR
- ___primary key is phraseIdentifier
postedPhrase
- savedPhrase - INT UNSIGNED - foreign key references savedPhrase(phraseIdentifier)
- username - VARCHAR
- timeReposted - TIMESTAMP
- ___primary key is combination of all listed fields
Current Best Attempt with Behavior
I'm self-taught/learning MySQL and believe I struggle with joins
. I think I should be using at least one left outer join
as seen in the graphic below. The left table will be savedPhrase
and the right will be postedPhrase
.
SELECT * FROM savedPhrase S
LEFT JOIN postedPhrase P
ON (S.phraseIdentifier = P.savedPhrase AND P.username = ?)
WHERE
(P.savedPhrase IS NULL OR P.timeReposted < DATE_SUB(NOW(), INTERVAL 14 day)) AND
S.associatedCategory = ?
The query above ALMOST works. However, once a single postedPhrase
row exists at least two weeks ago, it will return the joined savedPhrase
, even if one has been posted on the same account with the same identifier less than two weeks ago.
Further Discussion
The place where I'm having difficulty is the "absence condition". This is where a savedPhrase
must not exist within the last two weeks. In the previous paragraph I explained how the absence is not functioning because the postedPhrase
s are being returned based on their own independent timeReposted
. It seems I should be adding the absence condition to the right circle of the left outer join. Simplification of when to apply the conditions to the ON
versus the WHERE
would be very helpful.
I've worked at fixing this problem for a while and would appreciate any direction. Please let me know if I can include any other information.