sql >> Databáze >  >> RDS >> Mysql

Je to možné s mysql?

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()


  1. MySQL - Vybrat vše kromě toho, co je v této tabulce

  2. mysql - vyhledávání mezi daty, kde se zobrazují všechna data

  3. vypočítat součet času typu pomocí sql

  4. AttributeError:__exit__ na pythonu 3.4