Avatar billede willyrap Nybegynder
02. maj 2006 - 21:03 Der er 6 kommentarer og
1 løsning

GROUP BY interval

Jeg burde selv kende svaret på det her, men det gør jeg altså ikke :-(.

Jeg kører en webservice, hvor jeg logger hver gang en bruger foretager sig noget bestemt. Det foregår i en generel log-tabel med som bl.a. "time"-felt (INT - unix timestamp) og et "type"-felt (TEXT).
Jeg vil gerne lave et udtræk over hvor mange brugere som har downloaded i perioden $from til $to (unix timestamps) i intervaller af 5 minutter e.l.
-Hvis $from=0, $to=12, og $interval=4 vil jeg gerne have #downloads i hver af de tre perioder 0-3, 4-7, 8-11.
Dette skal gerne ske ved netop en forespørgsel.

Tænker at det er noget i retningen af
SELECT COUNT(*) FROM table WHERE type='download' AND time>=$from AND time<$to GROUP BY time INTERVAL 5*60

Det er især det første og sidste jeg kager i. Er jeg på rette spor? Nogle forslag?
Avatar billede kjulius Novice
03. maj 2006 - 00:52 #1
Nu har jeg ingen adgang til en server med MySQL installeret, så det må blive et gæt. Du foreslår selv en GROUP BY, så hvad med noget som dette?

SELECT FROM_UNIXTIME(FLOOR('time' / 300) * 300, GET_FORMAT(DATETIME,'EUR')) AS FraTidspunkt, FROM_UNIXTIME(FLOOR('time' / 300) * 300 + 299, GET_FORMAT(DATETIME,'EUR')) AS TilTidspunkt, COUNT(*)
FROM table
WHERE type='download'
  AND time>=$from
  AND time<$to
GROUP BY FROM_UNIXTIME(FLOOR('time' / 300) * 300, GET_FORMAT(DATETIME,'EUR')), FROM_UNIXTIME(FLOOR('time' / 300) * 300 + 299, GET_FORMAT(DATETIME,'EUR'))
Avatar billede willyrap Nybegynder
06. maj 2006 - 18:49 #2
Hej !

Jeg ved ikke lige hvorfor du vil oversætte timestamp til en dato-string, men jeg får ihvertfald følngende fejl:

#1064 - You have an error in your SQL syntax.  Check the manual that corresponds to your MySQL server version for the right syntax to use near '( DATETIME , 'EUR' ) ) AS fra , FROM_UNIXTIME( FLOOR( 'time' /

Jeg har prøvet at fjerne GET_FORMAT parameteren, og så får jeg følgende output med COUNT(*) AS cnt:

FraTidspunkt            TilTidspunkt            cnt    
1970-01-01 01:00:00    1970-01-01 01:04:59    969
(Kun den ene række)

cnt svarer det samtlige rækker i tabellen med typen 'download', så det er ikke helt korrekt, men derhen af :-) Hvad mangler der?
Avatar billede kjulius Novice
06. maj 2006 - 20:09 #3
Det kan kun blive et gæt, men jeg gætter på, at det er dine værdier i $from og $to der ikke er rigtige. Disse værdier skal indeholde dato/tidspunkt omsat til antal sekunder siden 1.1.1970 (definitionen på en unix timestamp ).

Du angiver i dit spørgsmål, at du vil sætte $from til 0 og $til til 12. Dvs. hele dit interval vil ligge mellem 1.1.1970-00:00:00 og 1.1.1970-00:00:12. Eller det skulle man tro. Men da unix time (http://en.wikipedia.org/wiki/Unix_time) er baseret på UTC (http://en.wikipedia.org/wiki/UTC), kører vi i danmark én time forskudt og så vises det også som sådan. Omsat til et interval på 5 min. vil det bevirke det interval der vises når forespørgslen køres.

Det kan bare undre mig, at alle dine rækker ligger i det interval. Har du tjekket inholdet at dit 'time' felt? Er det virkeligt en unix timestamp?
Prøv evt. at skrive:

SELECT 'time', FROM_UNIXTIME('time')
FROM table

Ser indholdet fornuftigt ud?

Mht. syntaxfejlen ved brug af GET_FORMAT, så er jeg lidt på herrens mark, da jeg har skrevet direkte af fra manualen. Måske er det et versions-spørgsmål. Der sker undertiden meget med MySQL mellem versionerne, også mht. de funktioner den understøtter og mht. syntaxen af bestående funktioner.
Men hele formålet med det var at få resultatet ud formateret i europæisk format. Det ser ud til at det er det den bruger som standard, så der sker åbenbart ikke noget ved at udelade funktionen.
Avatar billede willyrap Nybegynder
06. maj 2006 - 22:17 #4
Hej igen.

Jeg havde justeret mine $from og $to til at tage alt fra 1.1.1970 til et godt stykke ud i fremtiden (2000000000). Problemet var at du har single-quote (') rundt om time, hvilket åbenbart evaluerer til 0 (=1.1.1970), og derfor fik jeg dette sjove resultat. -Måske også et versionsspørgsmål. Men uden qoutes virker det (næsten) som det var meningen...

Jeg ville nemlig som sagt helst undgå ekstraarbejde ved at oversætte til datostrings, da mit PHP-script nok tage sig af at oversætte begge veje. Derfor blev den endelige løsning cirka:

SELECT FLOOR( time /3600 ) *3600 AS FraTidspunkt, FLOOR( time /3600 ) *3600 +3599 AS TilTidspunkt, COUNT( * ) AS cnt
FROM table
WHERE TYPE = 'download'
AND time >=$from
AND time <$to
GROUP BY FLOOR( time /3600 ) *3600, FLOOR( time /3600 ) *3600 +3599

(for intervaller på en time)

PS. Jeg ved godt i store træk hvad et timestamp er. Jeg skrev tallene 0 og 12 for at give et simpelt eksempel.  :-)

Kan du ikke lige smide et svar, så du kan få dine points?
Avatar billede kjulius Novice
06. maj 2006 - 22:55 #5
Tak, at smide et svar et meget let.. :-) Godt du fik det til at fungere. Grunden til at jeg troede, du ville have datoerne konverteret er, at det normalt er mere effektivt at lade databasen tage sig af så meget som muligt, i stedet for at lade et scipt gøre det. Jeg gik ud fra, at du ønskede at vise resultatet til et menneske, og helt ærligt er der vist ikke mange mennesker, der umiddelbart kan fortolke et unix timestamp, som ikke er blevet konverteret. That's why! Men hvis du foretrækker, at gøre det i et script, well, who am I to disaggree, it's your party!
Avatar billede willyrap Nybegynder
06. maj 2006 - 23:04 #6
Der er selvfølgelig et menneske som skal se det på et eller andet tidspunkt, og vi kan da hurtigt blive enige om at man hurtigt vil blive træt af at kigge på timestamps :-). Det kan også være at jeg ender med at lade databasen tage sig af det. Jeg ville bare starte så simpelt som muligt ;-)
Men tak for hjælpen!
Avatar billede kjulius Novice
06. maj 2006 - 23:04 #7
Tak for points!
Det med hvor man placerer sine konverteringer og beregninger er vist en smagssag. Som du nu ved er jeg varm tilhænger af, at placere mest muligt på databaseniveau. Der er dog ingen facitliste, og måske godt det samme... ;-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester