Mysql
 sql >> база данни >  >> RDS >> Mysql

Възможно ли е това с mysql?

Друга актуализация: Случайно (чрез копиране и поставяне) имаше 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()


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Намерете общия брой резултати в mySQL заявка с offset+limit

  2. MySQL Изберете само излишните редове и пропуснете оригиналните редове

  3. Това защитен метод ли е за вмъкване на данни от формуляра в MySQL база данни?

  4. Php Mysql Търсене между две дати

  5. Заявка за инжектиране на MySQL