En anden opdatering: Ved et uheld (ved copy&paste) havde starttime = ... or starttime = ...
men det skal være starttime = ... or endtime = ...
OPDATERING:
For at forklare min forespørgsel mere detaljeret (i den sidste forespørgsel er der endnu flere kommentarer):
Først fik vi bare
SELECT
...
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
Det er ikke mere som at sige "giv mig alle brugere, hvis session startede i dag eller sluttede i dag". At skulle overveje disse to gange igen og igen gør forespørgslen lidt klodset, men faktisk er det ikke så kompliceret.
Så normalt ville vi bruge COUNT()-funktionen til at tælle noget, selvfølgelig, men da vi ønsker "betinget tælling", bruger vi simpelthen SUM()-funktionen og fortæller den, hvornår den skal tilføje 1 og hvornår ikke.
SUM (CASE WHEN ... THEN 1 ELSE 0 END) AS a_column_name
Funktionen SUM() undersøger nu hver række i resultatsættet af sessioner fra i dag. Så for hver bruger i dette resultatsæt ser vi, om denne bruger var online den dato, vi angiver. Det er ligegyldigt, hvor mange gange han/hun var online, så af præstationsmæssige årsager bruger vi EXISTS
. Med EXISTS
du kan angive en underforespørgsel, der stopper, så snart noget er fundet, så det er lige meget, hvad det returnerer, når noget er fundet, så længe det ikke er NULL
. Så bliv ikke forvirret, hvorfor jeg valgte 1
. I underforespørgslen skal vi forbinde den bruger, som i øjeblikket undersøges fra den ydre forespørgsel, med brugeren fra den indre forespørgsel (underforespørgsel) og angive tidsvinduet. Hvis alle kriterier opfylder tæller 1 ellers 0 som forklaret før.
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterday,
Så laver vi en kolonne for hver betingelse og voila, du har alt hvad du behøver i én forespørgsel. Så med dit opdaterede spørgsmål er dine kriterier ændret, vi skal bare tilføje flere regler:
SELECT
/*this is like before*/
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndThursday,
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 2 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 2 DAY)))
/*this one here is a new addition, since you don't want to count the users that were online yesterday*/
AND NOT EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndWednesdayButNotThursday,
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 3 DAY) /* minus 3 days to get tuesday*/
OR (date(endtime) = CURDATE() - INTERVAL 3 DAY)))
/*this is the same as before, we check again that the user was not online between today and tuesday, but this time we really use BETWEEN for convenience*/
AND NOT EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndTuesdayButNotThursdayAndNotWednesday,
.../*and so on*/
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
Så jeg håber du får ideen nu. Har du flere spørgsmål? Spørg endelig.
slut på opdatering
Svar på tidligere version af spørgsmålet:
select
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterday,
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterdayOrTheDayBeforeYesterday,
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndWithinTheLastWeek
from gc_sessions s
where date(starttime) = CURDATE()
or date(endtime) = CURDATE()