Друга актуализация: Случайно (чрез копиране и поставяне) имаше starttime = ... or starttime = ...
но трябва да е starttime = ... or endtime = ...
АКТУАЛИЗАЦИЯ:
За да обясня запитването си по-подробно (в последното запитване има още повече коментари):
Първо просто получихме
SELECT
...
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
Това не е нищо повече от това да кажеш „дай ми всички потребители, чиято сесия е започнала днес или е приключила днес“. Това, че трябва да разглеждате тези два пъти отново и отново, прави заявката малко тромава, но всъщност не е толкова сложно.
Така че обикновено използваме функцията COUNT(), за да преброим нещо, очевидно, но тъй като искаме „условно броене“, ние просто използваме функцията SUM() и й казваме кога да добави 1 и кога не.
SUM (CASE WHEN ... THEN 1 ELSE 0 END) AS a_column_name
Функцията SUM() проверява сега всеки ред в резултатния набор от сесии от днес. Така че за всеки потребител в този набор от резултати ние гледаме дали този потребител е бил онлайн на датата, която сме посочили. Няма значение колко пъти той/тя е бил онлайн, така че от съображения за ефективност използваме EXISTS
. С EXISTS
можете да посочите подзаявка, която спира веднага щом нещо бъде намерено, така че няма значение какво връща, когато нещо бъде намерено, стига да не е NULL
. Така че не се обърквайте защо избрах 1
. В подзаявката трябва да свържем потребителя, който в момента се изследва от външната заявка, с потребителя от вътрешната заявка (подзаявка) и да посочим времевия прозорец. Ако всички критерии отговарят, броете 1, иначе 0, както е обяснено по-горе.
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,
След това правим колона за всяко условие и готово, имате всичко необходимо в една заявка. Така че с актуализирания ви въпрос критериите ви се промениха, просто трябва да добавим още правила:
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()
Така че, надявам се сега да схванете идеята. Още въпроси? Чувствайте се свободни да попитате.
край на актуализацията
Отговор на предишна версия на въпрос:
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()