31. maj 2002 - 14:39Der er
24 kommentarer og 1 løsning
Tricky SELECT
Hejsa... jeg har et KÆMPE effektivitetsproblem:
$firstresult = mysql_query("SELECT * FROM stat_hits WHERE path = '$path'");
while($row = mysql_fetch_array($firstresult)){ $secondres = mysql_query("SELECT * FROM stat_hits WHERE sesid = '".$row["sesid"]."' AND date > '".$row["date"]."' ORDER BY date ASC LIMIT 1");
while($row2 = mysql_fetch_array($secondres)){
if(3600 > (strtotime($row2["date"])-strtotime($row["date"])) and (strtotime($row2["date"])-strtotime($row["date"])) > 5){
Tabelen ser sådan her ud: [SESID|DATE|PATH] og med den kan man tracke brugere, sesid er php's sessionid og resten gir sig selv. Path der den aktuelle side... Med følgende stump kode kan jeg få gennemsnitstiden en bruger er om at besøge på hjemmesiden med
echo round($points/$devideby)." sekunder";
men findes der ikke en mere optimeret løsning da det tager ca 6 sek hvis der har været 200 visninger af en side...
Jeg kunne forestille mig at det kunne lade sig gøre hvis jeg havde en eksakt kopi af tabellen, og derefter lavede et "dobbelttabelsselect" men findes der en måde så jeg kan fx lave et alias til tabellen... for så var livet sq meget lettere...
Du kan joine tabellen sammen med sig selv på denne måde:
SELECT * FROM stat_hits A, stat_hits B WHERE A.path = '$path' AND B.sesid = A.sesid AND B.date > A.date ORDER BY B.date ASC LIMIT 1
Synes godt om
Slettet bruger
31. maj 2002 - 14:55#2
Kewl!! Jeg havde set noget med Join men jeg havde aldrig lige fattet hvad det gik ud på ... det var sq smart... jeg tester lige... pointene kommer snart...
Synes godt om
Slettet bruger
31. maj 2002 - 14:59#3
Hvis du lige kan smide gennemsnit ind, så kunne det være super... men der lidt problemer i sær med LIMIT 1, selv om jeg jo kun skal have den tid der ligger LIGE efter den oprindelige...
Synes godt om
Slettet bruger
31. maj 2002 - 15:06#4
Ah... jeg har en ide... finde minimumsværdien mellem de to dates og selecte den der har den...
Uden at jeg lige kan gennemskue din beregning skal det måske gøres sådan her:
WHERE (strtotime(B.date)-strtotime(A.date)) between 5 and 3600.
Jeg er ikke så stærk til php eller hvilket sprog det nu er lavet i. Hvis du siger hvad du vil have ud af sql'en, skal jeg se hvad der kan laves.
Synes godt om
Slettet bruger
31. maj 2002 - 15:19#6
Jeg har følgende select og det er det jeg skal bruge har jeg fundet ud af:
SELECT *,MIN(UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date)) AS mindif, AVG(UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date)) AS gennemsnittet FROM stat_hits A, stat_hits B WHERE A.path = '/Nyheder' AND B.sesid = A.sesid AND B.date > A.date AND mindif = (UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date))
mindif er ikke en kolonne, og er derfor ikke tilladt i WHERE.
Synes godt om
Slettet bruger
31. maj 2002 - 15:26#10
Det kan den ikke... desværre... den laver en anden fejl SQL-forespørgsel :
SELECT *, AVG(UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date)) AS gennemsnittet FROM stat_hits A, stat_hits B WHERE A.path = '/Nyheder' AND B.sesid = A.sesid AND B.date > A.date AND MIN(UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date)) = (UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date)) LIMIT 0, 30
Ja, selvfølgelig. MIN, MAX, AVG er jo gruppefunktioner og de kan naturligvis ikke benyttes i WHERE clauses. MySQL supporterer desværre heller ikke sub-selects, så der kan den heller ikke fixes. Prøv i stedet at sortere på kolonnen, så vil du kunne bruge LIMIT til at få de rigtige rækker ud.
Synes godt om
Slettet bruger
31. maj 2002 - 15:42#12
Det sq ærgeligt... hvad hvis jeg bruger noget lign GROUP BY sesid
Synes godt om
Slettet bruger
31. maj 2002 - 15:45#13
Hvis jeg bruger subselects... så er jeg jo ligevidt
Jeg bliver desværre nødt til at løbe nu,´men jeg skal gerne kigge på det i løbet af weeekenden.
Synes godt om
Slettet bruger
31. maj 2002 - 16:08#16
ok tak.. her er lidt point til at hjælpe på det...
Indtil videre virker:
SELECT AVG(UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date)) AS gennemsnittet FROM stat_hits A, stat_hits B WHERE A.path = '/Nyheder' AND B.sesid = A.sesid AND B.date > A.date
SELECT A.Path, A.SESID, A.Date, B.date, AVG(UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date)) AS gennemsnit FROM stat_hits A, stat_hits B WHERE A.path = '/Nyheder' AND B.sesid = A.sesid AND B.date > A.date GROUP BY A.Path, A.SESID, A.Date, B.date HAVING MIN(UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date)) = (UNIX_TIMESTAMP(B.date)-UNIX_TIMESTAMP(A.date))
Jeg forstår bare ikke helt hvad du forsøger. Du har dataene [SESID|DATE|PATH], hvornår bliver de sat ind i databasen, er det når en bruger får vist en side? Så er dato vel det tidspunkt hvor siden bliver vist. Men hvad viser så udtrykket a.date-b.date?
Synes godt om
Slettet bruger
01. juni 2002 - 23:09#18
ja.... a.date-b.date viser så hvor lang tid en bruger er om at klikke videre til den næste side.. så er AVG as gennemsnit den gennemsnitlige tid en bruger besøger en side, før han /hun går videre..
Synes godt om
Slettet bruger
01. juni 2002 - 23:09#19
jeg tester senere, men pga jeg ikke har fået mails hele dagen, er der lange svartider :D
OK, så du måler den tid en bruger er inde på en side. Men hvis en bruger går over på en anden "site" får du vel ikke den information?
Synes godt om
Slettet bruger
01. juni 2002 - 23:25#22
nej! derfor B.date > A.date, for der skal jo eksistere en handling når han/hun går videre.... jeg synes bare det var en sjov feature! men den er lige processkrævende om det er php eller mysql der gør de... men tak for hjælpen!
Har du evt. overvejet at indeksere felterne i tabellen - det kan også give dig et boost!
Synes godt om
Slettet bruger
03. juni 2002 - 23:32#24
indexere? forklar!
Synes godt om
Slettet bruger
03. juni 2002 - 23:38#25
WOHAHOWWHAOHW!!!!!!!!! Det hjalp
Synes godt om
Ny brugerNybegynder
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.