Hello, lets imagine i have table ads and table adsClicks. …
table ads holds banner links
table adsClicks holds IP clicks on banner
I want to show user only link banners that user has not ever clicked or did click 24+ hours ago
Here is my code:
$time = time() + 86400; //PHP
SELECT a.*
FROM ads AS a
WHERE (
(a.id NOT IN(SELECT ad FROM adsClicks WHERE ad=a.id AND ip='00.00.00.00'))
OR
(a.id IN(SELECT ad FROM adsClicks WHERE ad=a.id AND ip='00.00.00.00' AND time>'".$time."')
)
AND a.status='Active' AND clicksLeft>0
Query does work but still does give banner links that user has clicked in last 24 hours
Whats the issue? Also maybe there are better way to write it (left join - could not figure out correct syntax)?
$time = time() - 86400; //PHP
SELECT a.*
FROM ads AS a
WHERE (
(a.id NOT IN (SELECT ad FROM adsClicks WHERE ip = :ip GROUP BY ad))
OR
(a.id IN (SELECT ad FROM adsClicks WHERE ip = :ip AND time > :time GROUP BY ad)
)
AND a.status='Active' AND clicksLeft>0
I have not tested yet. … But just to be sure. … What does GROUP BY do in this case? also for check if was clicked? Does it looks at latest click (they can be multiple clicks)?
$time = time() - 86400; //PHP
SELECT a.*
FROM ads AS a
WHERE (
(a.id NOT IN (SELECT UNIQUE ad FROM adsClicks WHERE ip = :ip))
OR
(a.id IN (SELECT UNIQUE ad FROM adsClicks WHERE ip = :ip AND time > :time)
)
AND a.status='Active' AND clicksLeft>0
Before I get accused of not being helpful…
The original query, fixed:
$time = time() - 86400; //PHP
SELECT a.*
FROM ads AS a
WHERE (
(a.id NOT IN (SELECT UNIQUE ad FROM adsClicks WHERE ip = :ip))
OR
(a.id IN (SELECT UNIQUE ad FROM adsClicks WHERE ip = :ip AND time > :time)
)
AND a.status='Active' AND clicksLeft>0
Why the logic should be inverted, and what that translates as:
The conditional, however, is overlapping as written:
“Has not ever clicked or did click 24 hours ago”
This can be better stated by stating what you’re NOT trying to find:
“Don’t find any ad that has been clicked in the last 24 hours.”
You’ve restated the condition, as a singular clause.
Which means the query can become:
SELECT a.*
FROM ads AS a
WHERE a.id NOT IN (SELECT UNIQUE ad FROM adsClicks WHERE ip = :ip AND `time` > :yesterday )
AND a.status='Active'
AND clicksLeft>0
(Though i would heartily recommend a LIMIT clause… maybe an ORDER BY…)
In other words i need query that shows me result from ads that user has never been clicked or clicked 24 or more hours ago (if last click was 24 hours and 1 second ago user should see ad again)
Again i have not tested as i m not on my laptop yet. …
But this statement is the SAME as saying “I need query that shows me result from ads that are NOT user has clicked and clicked 24 or less hours ago”
Inverting logic: Stick “NOT” in front of the sentence. Change “or” to “and” (and vice versa), change “more” to "less’ (and vice versa), remove negatives, and you get equivalent statements.
Think of it this way: I have 5 oranges and 3 apples. The apples are 2 red and 1 green.
I could say “I need a query that finds fruits that are green and apples.” or, I could say “I need a query that finds fruits that are not red or oranges”. Both of them would find the same result.
SELECT a.*
FROM ads AS a
WHERE a.id NOT IN (SELECT UNIQUE ad FROM adsClicks WHERE ip = :ip AND `time` > :yesterday )
AND a.status='Active'
AND clicksLeft>0