sql >> Database >  >> RDS >> Mysql

Is dit mogelijk met mysql?

Nog een update: Per ongeluk (door kopiëren en plakken) had starttime = ... or starttime = ... maar het moet starttime = ... or endtime = ... . zijn

UPDATE:

Om mijn vraag in meer detail uit te leggen (in de laatste vraag zijn er nog meer opmerkingen):

Eerst kregen we gewoon

SELECT
...
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()

Dat is niets meer als zeggen "geef me alle gebruikers van wie de sessie vandaag is begonnen of vandaag is geëindigd". Die twee keer opnieuw moeten overwegen, maakt de query een beetje onhandig, maar eigenlijk is het niet zo ingewikkeld.

Normaal gesproken zouden we dus de functie AANTAL() gebruiken om iets te tellen, maar omdat we "voorwaardelijk tellen" willen, gebruiken we gewoon de functie SOM() en vertellen het wanneer 1 moet worden toegevoegd en wanneer niet.

SUM (CASE WHEN ... THEN 1 ELSE 0 END) AS a_column_name

De functie SUM() onderzoekt nu elke rij in de resultatenset van sessies van vandaag. Dus voor elke gebruiker in deze resultatenset kijken we of deze gebruiker online was op de datum die we specificeren. Het maakt niet uit hoe vaak hij/zij online was, dus om prestatieredenen gebruiken we EXISTS . Met EXISTS je kunt een subquery specificeren die stopt zodra er iets wordt gevonden, dus het maakt niet uit wat het retourneert als er iets wordt gevonden, zolang het maar niet NULL is . Dus raak niet in de war waarom ik 1 heb gekozen . In de subquery moeten we de gebruiker die momenteel wordt onderzocht vanuit de buitenste query verbinden met de gebruiker van de innerlijke query (subquery) en het tijdvenster specificeren. Als alle criteria voldoen tel 1 anders 0 zoals eerder uitgelegd.

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,

Dan maken we een kolom voor elke voorwaarde en voila, je hebt alles wat je nodig hebt in één vraag. Dus met uw bijgewerkte vraag zijn uw criteria gewijzigd, we moeten alleen meer regels toevoegen:

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

Dus ik hoop dat je het idee nu snapt. Nog meer vragen? Vragen staat vrij.

einde update

Antwoord op vorige versie van vraag:

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 filmreserveringssysteem ontwerp deel 2

  2. Negeer null-resultaten in MySQL JOIN-query's

  3. SQL-scripts uitvoeren op docker-container

  4. Mysql CREATE DEFINER