Kolejna aktualizacja: Przypadkowo (przez kopiowanie i wklejanie) miał starttime = ... or starttime = ...
ale powinno to być starttime = ... or endtime = ...
AKTUALIZACJA:
Aby dokładniej wyjaśnić moje zapytanie (w ostatnim pytaniu jest jeszcze więcej komentarzy):
Najpierw po prostu otrzymaliśmy
SELECT
...
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
To nic innego jak powiedzenie „daj mi wszystkich użytkowników, których sesja rozpoczęła się dzisiaj lub dzisiaj się zakończyła”. Konieczność ponownego rozważenia tych dwóch razy sprawia, że zapytanie jest trochę niezgrabne, ale w rzeczywistości nie jest to takie skomplikowane.
Tak więc zwykle używamy funkcji COUNT(), aby coś policzyć, ale ponieważ chcemy "zliczania warunkowego", po prostu używamy funkcji SUMA() i mówimy, kiedy dodać 1, a kiedy nie.
SUM (CASE WHEN ... THEN 1 ELSE 0 END) AS a_column_name
Funkcja SUM() sprawdza teraz każdy wiersz w zestawie wyników sesji od dzisiaj. Tak więc dla każdego użytkownika w tym zestawie wyników sprawdzamy, czy ten użytkownik był online w określonej przez nas dacie. Nie ma znaczenia, ile razy był online, więc ze względu na wydajność używamy EXISTS
. Z EXISTS
możesz określić podzapytanie, które zatrzymuje się, gdy tylko coś zostanie znalezione, więc nie ma znaczenia, co zwraca, gdy coś zostanie znalezione, o ile nie jest to NULL
. Więc nie daj się zwieść, dlaczego wybrałem 1
. W podzapytaniu musimy połączyć użytkownika aktualnie badanego z zapytania zewnętrznego z użytkownikiem z zapytania wewnętrznego (podzapytanie) i określić okno czasowe. Jeśli wszystkie kryteria spełniają liczbę 1, jeszcze 0, jak wyjaśniono wcześniej.
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,
Następnie tworzymy kolumnę dla każdego warunku i voila, masz wszystko, czego potrzebujesz w jednym zapytaniu. Tak więc wraz z Twoim zaktualizowanym pytaniem zmieniły się Twoje kryteria, musimy tylko dodać więcej reguł:
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()
Więc mam nadzieję, że teraz wpadniesz na ten pomysł. Jakieś pytania? Śmiało pytaj.
koniec aktualizacji
Odpowiedź na poprzednią wersję pytania:
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()