Další aktualizace: Náhodně (zkopírovat a vložit) měl starttime = ... or starttime = ...
ale mělo by to být starttime = ... or endtime = ...
AKTUALIZACE:
Abych vysvětlil svůj dotaz podrobněji (v závěrečném dotazu je ještě více komentářů):
Nejprve jsme prostě dostali
SELECT
...
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
To není nic jiného, než říct „dejte mi všechny uživatele, jejichž relace dnes začala nebo skončila“. Když je budete muset znovu a znovu zvažovat, je dotaz trochu neohrabaný, ale ve skutečnosti to není tak složité.
Obvykle bychom tedy použili funkci COUNT() k počítání, samozřejmě, ale protože chceme "podmíněné počítání", jednoduše použijeme funkci SUM() a řekneme jí, kdy má přidat 1 a kdy ne.
SUM (CASE WHEN ... THEN 1 ELSE 0 END) AS a_column_name
Funkce SUM() nyní zkoumá každý řádek ve výsledné sadě relací z dneška. U každého uživatele v této sadě výsledků se tedy podíváme, zda byl tento uživatel online k datu, které zadáme. Nezáleží na tom, kolikrát byl online, takže z důvodu výkonu používáme EXISTS
. S EXISTS
můžete zadat poddotaz, který se zastaví, jakmile je něco nalezeno, takže nezáleží na tom, co vrátí, když je něco nalezeno, pokud to není NULL
. Nenechte se tedy zmást, proč jsem zvolil 1
. V poddotazu musíme propojit uživatele, který je aktuálně zkoumán z vnějšího dotazu, s uživatelem z vnitřního dotazu (poddotazu) a určit časové okno. Pokud všechna kritéria splňují, počítejte 1 jinak 0, jak bylo vysvětleno dříve.
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,
Poté vytvoříme sloupec pro každou podmínku a voila, vše, co potřebujete, máte v jednom dotazu. Takže s vaší aktualizovanou otázkou se vaše kritéria změnila, jen musíme přidat další pravidla:
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()
Tak doufám, že teď už ten nápad pochopíte. Nějaké další otázky? Klidně se zeptej.
konec aktualizace
Odpověď na předchozí verzi otázky:
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()