sql >> Databasteknik >  >> RDS >> Mysql

Är detta möjligt med mysql?

En annan uppdatering: Av misstag (genom copy&paste) hade starttime = ... or starttime = ... men det ska vara starttime = ... or endtime = ...

UPPDATERING:

För att förklara min fråga mer detaljerat (i den sista frågan finns det ännu fler kommentarer):

Först fick vi helt enkelt

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

Det är inget mer som att säga "ge mig alla användare vars session började idag eller slutade idag". Att behöva överväga dessa två gånger om och om igen gör frågan lite klumpig, men det är faktiskt inte så komplicerat.

Så vanligtvis skulle vi använda COUNT()-funktionen för att räkna något, uppenbarligen, men eftersom vi vill ha "villkorlig räkning" använder vi helt enkelt SUM()-funktionen och talar om när den ska lägga till 1 och när inte.

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

Funktionen SUM() undersöker nu varje rad i resultatuppsättningen av sessioner från idag. Så för varje användare i denna resultatuppsättning ser vi om denna användare var online det datum vi anger. Det spelar ingen roll hur många gånger han/hon var online, så av prestationsskäl använder vi EXISTS . Med EXISTS du kan ange en underfråga som slutar så fort något hittas, så det spelar ingen roll vad det returnerar när något hittas, så länge det inte är NULL . Så bli inte förvirrad varför jag valde 1 . I underfrågan måste vi koppla den användare som för närvarande granskas från den yttre frågan med användaren från den inre frågan (underfrågan) och ange tidsfönstret. Om alla kriterier uppfyller räknas 1 annars 0 som förklarats tidigare.

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,

Sedan gör vi en kolumn för varje villkor och vips, du har allt du behöver i en fråga. Så med din uppdaterade fråga har dina kriterier ändrats, vi måste bara lägga till fler regler:

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

Så jag hoppas att du förstår idén nu. Några fler frågor? Var inte rädd för att fråga.

slut på uppdatering

Svar på tidigare version av frågan:

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. Hur ändrar jag SQL Server 2005 till att vara skiftlägeskänslig?

  2. Ta reda på om användaren fick tillstånd att välja/uppdatera/... en tabell/funktion/... i PostgreSQL

  3. Oracle-baserad PIVOT med flera kolumner grupp

  4. Hur ställer jag in standardschemat för en användare i MySQL