Avatar billede buttersi Nybegynder
29. april 2007 - 15:05 Der er 36 kommentarer og
1 løsning

Hjælp med top10

Jeg er igang med at lave en form for top10 liste. Listen bliver lavet udfra hvor mange hits de forskellige videoer på min hjemmeside har fået.

Når jeg laver listen ser min kode således ud:

      <?php
      include "include/connect.txt";
       
        $query = mysql_query("SELECT * FROM htv_video ORDER by hits DESC limit 10");
        while($data = mysql_fetch_array($query)) {
       
        echo ''.$data[titel].'<br>';
       
        }
      ?>


Nu viser den hvilke videoer der har fået flest hits ialt. Men hvad nu hvis jeg gerne vil vise hvem der har fået flest hits inden for den sidste uge. Hvordan gør jeg det?
Avatar billede bauerdata Nybegynder
29. april 2007 - 15:28 #1
så har du forhåbenligt en dato for hver enkelt hit ?-)

SELECT *
FROM htv_video
WHERE DATE_SUB(CURDATE(),INTERVAL 7 DAY) <= date_col
ORDER by hits DESC
limit 10

noget i den stil. Mysql har vist et timestamp på alle rekords så brug den,
:-)
Avatar billede buttersi Nybegynder
29. april 2007 - 15:33 #2
Det eneste jeg har lavet er et felt der hedder hits :-/
Avatar billede jensgram Nybegynder
29. april 2007 - 15:34 #3
Så bliver du nødt til at gemme dine hits med et timestamp. Du kan enten gemme dem hver i sær (én record pr. hit) eller pr. uge o.lign. Den første løsning muliggør de mest interessante beregninger.

Din hits-tabel skal blot have timestamp og fremmednøgle (i.e. nøglen / ID for den enkelte video).

Derefter kan du gruppere pr. nøgle og uge som sorteres efter uge...

Giver det mening?
Avatar billede jensgram Nybegynder
29. april 2007 - 15:34 #4
Hmmm - der var kommet 2 indlæg i mellemtiden :(
Avatar billede buttersi Nybegynder
29. april 2007 - 15:34 #5
Og så har jeg sat denne kode ind på hver video side

mysql_query( "UPDATE htv_video SET hits = hits + 1 WHERE id = " . $id );
Avatar billede buttersi Nybegynder
29. april 2007 - 15:36 #6
jensgram, det vil sige jeg skal lave en seperat tabel for hits. Lige nu har jeg bare et felt i min video tabel der hedder hits
Avatar billede jensgram Nybegynder
29. april 2007 - 15:37 #7
Ja, det vil det kræve.
Avatar billede buttersi Nybegynder
29. april 2007 - 15:39 #8
Nu har jeg lavet en tabel der ser således ud

CREATE TABLE `htv_hits` (
`videoid` INT NOT NULL ,
`hits` INT NOT NULL ,
`dato` TIMESTAMP NOT NULL
) ENGINE = MYISAM ;

Er det rigtigt?
Avatar billede jensgram Nybegynder
29. april 2007 - 15:44 #9
Nej, ikke helt. Der er ingen grund til en "hits"-kolonne, da du skal tænke hver record som et selvstændigt hit.

mysql_query("UPDATE htv_video SET hits = hits + 1 WHERE id = " . $id );

->

mysql_query('INSERT INTO htv_hits (videoid, dato) VALUES (' . $id . ', NOW())');
Avatar billede jensgram Nybegynder
29. april 2007 - 15:47 #10
Lidt optimering på din tabel:

CREATE TABLE `htv_hits` (
  `videoid` int(11) NOT NULL REFERENCES htv_video.id,
  `dato` timestamp(14) NOT NULL,
  PRIMARY KEY  (`videoid`,`dato`),
  KEY `videoid` (`videoid`)
) TYPE=MyISAM;
Avatar billede buttersi Nybegynder
29. april 2007 - 15:49 #11
Okay det har jeg rettet nu.

Nu gemmer den hvert hit med videoid'et og en dato.

Nu vil jeg så gerne lave en side der viser hvilke videoer der er mest besøgt inden for den seneste uge. Skal jeg så ud i noget som det Bauerdata skrev i det første indlæg?
Avatar billede bauerdata Nybegynder
29. april 2007 - 16:10 #12
select videoid, count(*) as hists
from htv_hits
WHERE DATE_SUB(CURDATE(),INTERVAL 7 DAY) <= timestamp
group by videoid
order by hists
limit 10
:-)
Avatar billede buttersi Nybegynder
29. april 2007 - 16:14 #13
Jeg er ikke sikker på om jeg har gjort det rigtige, fordi lige nu får jeg bare en blank side. Her er min kode

<?php
      include "include/connect.txt";
       
        $query = mysql_query("select videoid, count(*) as hits from htv_hits WHERE DATE_SUB(CURDATE(),INTERVAL 7 DAY) <= timestamp group by videoid order by hits limit 10");
        while($data = mysql_fetch_array($query)) {
       
        echo ''.$data[titel].'<br>';
       
        }
      ?>
Avatar billede jensgram Nybegynder
29. april 2007 - 16:22 #14
Vi skal lige have relationen med:

select h.videoid, count(h.*) as hists, v.*
from htv_hits AS h, htv_video AS v
WHERE DATE_SUB(CURDATE(),INTERVAL 7 DAY) <= h.timestamp AND
h.videoid = v.id
group by h.videoid
order by h.hists
limit 10
Avatar billede buttersi Nybegynder
29. april 2007 - 16:35 #15
Min kode ser nu således ud:

<?php
      include "include/connect.txt";

        $query = mysql_query("select h.videoid, count(h.*) as hists, v.*
from htv_hits AS h, htv_video AS v
WHERE DATE_SUB(CURDATE(),INTERVAL 7 DAY) <= h.timestamp AND
h.videoid = v.id
group by h.videoid
order by h.hists
limit 10");
        while($data = mysql_fetch_array($query)) {
       
        echo ''.$data[titel].'';
       
        }
      ?>


Men jeg får stadig en blank side ( http://www.arto-baggrunde.dk/htv/video_mestsete.php )
Avatar billede jensgram Nybegynder
29. april 2007 - 16:38 #16
Hmm - har du prøvet med en print_r($data) i din løkke --- bare for at se, om den indeholder noget?
Avatar billede buttersi Nybegynder
29. april 2007 - 16:40 #17
Det giver os en blank side :-/
Avatar billede jensgram Nybegynder
29. april 2007 - 16:41 #18
Hmmm - ja, så returnerer DB'en jo ikke noget.

Det var lidt mærkeligt.
Avatar billede buttersi Nybegynder
29. april 2007 - 16:47 #19
jeg prøvede lige at skrive

$video = mysql_query ("SELECT * FROM htv_video");

while($data = mysql_fetch_array($video)) {
       
        print_r($data[titel]);


så viser den alle titlerne
Avatar billede buttersi Nybegynder
29. april 2007 - 17:09 #20
Kan godt være jeg spørger dumt, men kan det være fordi der ikke er gået 7 dage endnu og at den først viser resultatet når den har kunne tælle hits fra 7 dage.
Avatar billede jensgram Nybegynder
29. april 2007 - 18:15 #21
Hvad så med:

$video = mysql_query ("SELECT v.*, h.* FROM htv_video AS v, htv_hits AS h WHERE v.id = h.videoid GROUP BY h.videoid");

while($data = mysql_fetch_array($video)) {
     
        print_r($data);
}
Avatar billede buttersi Nybegynder
29. april 2007 - 18:20 #22
Når jeg skriver som du lige har gjort altså:

<?php
      include "include/connect.txt";
     
        $video = mysql_query ("SELECT v.*, h.* FROM htv_video AS v, htv_hits AS h WHERE v.id = h.videoid GROUP BY h.videoid");

        while($data = mysql_fetch_array($video)) {
     
        print_r($data);
       
        }
      ?>


Kommer der en masse data frem
Avatar billede jensgram Nybegynder
29. april 2007 - 19:10 #23
Ok - så fortsætter vi derfra. Vi beholder bare den nuværende join, da vi ikke er interesserede i videoer uden hits.

SELECT v.*, COUNT(h.videoid) AS cnthits FROM htv_video AS v, htv_hits AS h WHERE v.id = h.videoid GROUP BY h.videoid ORDER BY COUNT(h.videoid) DESC, v.titel ASC

Det giver ikke dem med flest hits i denne uge, men den betingelse tager vi senere. Denne skulle gerne give et korrekt tal (cnthits) for hver video.
Avatar billede buttersi Nybegynder
29. april 2007 - 19:26 #24
Nu ser min kode såldes ud, men det giver en blank side:

<?php
      include "include/connect.txt";
     
        $video = mysql_query ("SELECT v.*, COUNT(h.videoid) AS cnthits FROM htv_video AS v, htv_hits AS h WHERE v.id = h.videoid GROUP BY h.videoid ORDER BY COUNT(h.videoid) DESC, v.titel ASC");

        while($data = mysql_fetch_array($video)) {
     
        print_r($data[titel]);
       
        }
      ?>


Har har jeg gjort forkert?
Avatar billede buttersi Nybegynder
30. april 2007 - 19:20 #25
Jeg prøver at lave et nyt spørgsmål. Jensgram smid et svar så du kan få point :)
Avatar billede jensgram Nybegynder
30. april 2007 - 21:33 #26
Hov, jeg har ikke lige fået set mine mails i gennem. Jeg undrer mig over at ovenstående ikke giver data. Du har nogle records i "hits"-tabellen? Ellers prøver vi en LEFT JOIN:

Prøv følgende:

<?php

include "include/connect.txt";

$video = mysql_query('SELECT v.*, COUNT(*) AS cnthits FROM htv_video AS v LEFT JOIN htv_hits AS h ON v.id = h.videoid GROUP BY h.videoid ORDER BY COUNT(*) DESC, v.titel ASC') or die(mysql_error());

while($data = mysql_fetch_array($video)) {
    print_r($data);
}

?>
Avatar billede jensgram Nybegynder
30. april 2007 - 21:37 #27
Hvis den giver resultater, så kan vi forsøge med

WHERE DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= h.dato

lige før GROUP BY...
Avatar billede jensgram Nybegynder
30. april 2007 - 21:39 #28
PS: Du har forhåbentlig ikke DB-pass m.m. i en .txt-fil? I så fald skal du ihvertfald sørge for, at mappen ikke er tilgængelig fra web-scope :)
Avatar billede buttersi Nybegynder
30. april 2007 - 23:20 #29
Hej jensgram, nu giver skriver den en fejl, "Invalid use of group function" kan ses her http://www.arto-baggrunde.dk/htv/video_mestsete.php
Avatar billede buttersi Nybegynder
30. april 2007 - 23:23 #30
min kode ser således ud:

<?php

include "include/connect.txt";

$video = mysql_query('SELECT v.*, COUNT(*) AS cnthits FROM htv_video AS v LEFT JOIN htv_hits AS h ON v.id = h.videoid WHERE DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= h.date GROUP BY h.videoid ORDER BY COUNT(*) DESC, v.titel ASC') or die(mysql_error());

while($data = mysql_fetch_array($video)) {
    print_r($data);
}

?>
Avatar billede jensgram Nybegynder
01. maj 2007 - 06:52 #31
Måske er det så mig, der bare har lavet en brain fart :)

Prøv

<?php

include "include/connect.txt";

$video = mysql_query('SELECT v.*, COUNT(*) AS cnthits FROM htv_video AS v LEFT JOIN htv_hits AS h ON v.id = h.videoid WHERE DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= h.date GROUP BY h.videoid ORDER BY cnthits DESC, v.titel ASC') or die(mysql_error());

while($data = mysql_fetch_array($video)) {
    print_r($data);
}

?>
Avatar billede buttersi Nybegynder
01. maj 2007 - 11:46 #32
Nu sker der noget! :-)

Ser ud til det virker perfekt nu. Lige et sidste spørgsmål, hvis jeg vil vise de mest sete videoer all time, hvad skal der så laves om? :-)
Avatar billede jensgram Nybegynder
01. maj 2007 - 14:14 #33
Det var da for åndssvagt - kan ikke se, hvorfor jeg kom til at smide COUNT-tingen efter ORDER BY, men der gik da noget tid før jeg fangede den :)

All time = fjern dato-delen (i.e. WHERE ...):

SELECT v.*, COUNT(*) AS cnthits FROM htv_video AS v LEFT JOIN htv_hits AS h ON v.id = h.videoid GROUP BY h.videoid ORDER BY cnthits DESC, v.titel ASC
Avatar billede jensgram Nybegynder
01. maj 2007 - 14:15 #34
Hov - så kommer der lige et svar.
Avatar billede buttersi Nybegynder
01. maj 2007 - 17:14 #35
Hehe :-)

Mange tak for hjælpen!
Avatar billede jensgram Nybegynder
01. maj 2007 - 19:51 #36
Velbekomme, du. Om en uges tid får vi så at se, om der er forskel på "mest populære lige nu" og "mest sete" :-)
Avatar billede buttersi Nybegynder
02. maj 2007 - 00:34 #37
Hehe ja, har dog prøvet at ændre 7 DAY til 1 DAY og så bliver tallet mindre :-) så det ser ud til at virke
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
Vi tilbyder markedets bedste kurser inden for webudvikling

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