[php] count probleem

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik wil graag van de laatste 7 dagen dagen weten hoeveel nieuwe leden er per dag bijgekomen zijn. Nu wordt bij elk lid de regdate bijgehouden. Ik ben zelf net aan het proberen geweerst maar kwam er niet echt uit.

Had wel een werkende oplossing:

PHP:
1
2
3
4
5
6
7
<?

$tijd = mktime(0,0,0,date("m") ,date("d")-7,date("Y"));
$result = mysql_query('SELECT * FROM gebruikers WHERE regdate > '.$tijd.'');
$totaal = mysql_num_rows($result);

?>

Dat 7x uitvoeren, met 7x een andere $tijd. Maar om nou 7 queries voor zo iets simpels te doen, leek me beetje gekken werk. Dus dacht ik aan een array.

PHP:
1
2
3
4
5
6
7
8
9
10
11
<?
$result = mysql_query('select count(1) as bleh FROM gebruikers WHERE regdate > '.$tijd.' GROUP BY regdate');

while ($row = mysql_fetch_array($result, MYSQL_ASSOC))  {

$nivo[$row['regdate']] = $row['bleh'];

}

// hier echo'en van output
?>

Maar dit bleek ook problemen te geven aangezien ik niet kan groeperen op REGDATE, omdat die nooit het zelfde is.

Zou iemand me opweg kunnen helpen met uitleg hoe ik dit beter kan aanpakken?

[ Voor 8% gewijzigd door Verwijderd op 29-06-2003 14:23 ]


Acties:
  • 0 Henk 'm!

  • sjroorda
  • Registratie: December 2001
  • Nu online
De snelste manier lijkt mij het gebruiken van de eerste query, zodat je dus alle nieuwe gebruikers terugkrijgt, en die sorteren op regdate. Vervolgens met PHP de verkregen array uitlezen en de bezoekers per dag tellen. Scheelt 6 queries. Weet niet of het ook binnen MySQL kan, maar ik denk het niet.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb het nu zo gedaan, alleen de output is nog niet goed :w

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?
$tijd = mktime(0,0,0,date("m") ,date("d")-7,date("Y"));

$result = mysql_query('select count(1) as bleh, regdate FROM gebruikers WHERE regdate > '.$tijd.' GROUP BY regdate');

while ($row = mysql_fetch_array($result, MYSQL_ASSOC))  {

$regdate = $row['regdate'];

$date = time();

$tot = ($date)-($regdate);

$tot = $tot/86400;

$tot = ceil($tot);

$nivo[$tot] = $row['bleh'];

}

echo $nivo[1];
echo $nivo[2];
echo $nivo[3];
echo $nivo[4];
echo $nivo[5];
echo $nivo[6];
echo $nivo[7];

?>



afgelopen 6 dagen is er niemand lid gworden, maar vandaag 3. Dus zou eigenlijk 6x 0 willen zien, en 1x 3. Maar output geeft 1x 1. Wat doe ik fout?

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Nu online
edit:
Ik had je tweede reactie niet gelezen; je bent al weer een stuk verder zie ik, dus mijn originele tekst al ten dele overbodig zijn...
De reden dat je dagen zonder nieuwe registraties niet terugkrijgt, is dat de dabase niet kan groeperen op wat 'ie niet kent. Als je de groenteboer vraagt hoeveel vruchten 'ie heeft, gegroepeerd bij vrucht, dan antwoord 'ie bijvoorbeeld: 10 appels, 12 peren, 3 bananen. Hij vindt het dan niet nodig om er aan toe te voegen dat 'ie 0 mango's, 0 kokosnoten, 0 lyches, 0 .... je krijgt het idee. :) Dan is 'ie oneindig lang bezig.

De oplossing is dus, om voor alle 7 dagen maar aan te nemen dat je 0 registraties kreeg, tenzij je er meer had. Je moet behalve het aantal registraties dus ook de datum selecteren (zodat een rij dus bestaat uit twee velden: het aantal registraties en de bijbehorende datum). Bij alle data die niet in het resultaat zitten horen schijnbaar 0 registraties.

Ik zou de resultaten dan ook in een associatieve array stoppen, waarbij de key de datum is en de value het aantal registraties. Bij het weergeven loop je de zeven data af en voor alle data die niet in je associatieve array zitten, geef je een 0 weer.
Verder met het echte probleem, dus:
Verwijderd schreef op 29 June 2003 @ 14:39:
afgelopen 6 dagen is er niemand lid geworden, maar vandaag 3. Dus zou eigenlijk 6x 0 willen zien, en 1x 3. Maar output geeft 1x 1. Wat doe ik fout?
Weet je zeker dat je 1x 1 krijgt en geen 1x 3? Anders lijkt me dat de inhoud van je database gewoon niet goed is.

Denk er trouwens aan dat je nu incrementele waarden krijgt (het aantal registraties in een afgelopen periode). Je wil dus waarschijnlijk niet gewoon element 1 tot en met zeven van $nivo printen, maar $nivo[7] - $nivo[6], $nivo[6] - $nivo[5], ... , $nivo[1] - $nivo[0], waarbij alle niet-bestaande array elementen uiteraard op 0 geinitialiseerd zouden moeten worden (al is undefined ook een soort 0 in PHP, maar zie de FAQ over dat soort programmeerpraktijken).

[ Voor 51% gewijzigd door Soultaker op 29-06-2003 15:04 ]


Acties:
  • 0 Henk 'm!

  • SWINX
  • Registratie: Juni 2001
  • Laatst online: 23-07 18:19
Ik snap het probleem niet zo, of denk ik te simpel?

PHP:
1
$result = mysql_query("SELECT COUNT(1) AS bleh, regdate FROM gebruikers WHERE regdate > ".$tijd." GROUP BY regdate ORDER BY regdate DESC");

[ Voor 8% gewijzigd door SWINX op 29-06-2003 15:40 ]

Mannen komen van Mars Tweakers, vrouwen van Venus Bokt


Acties:
  • 0 Henk 'm!

  • sjroorda
  • Registratie: December 2001
  • Nu online
Probleem is dat regdate een unix timestamp is, zodat verschillende tijden op dezelfde dag andere regdates zijn.

Kan je niets met een functie over regdate? Iets in de trant van
GROUP BY INT((regdate - 1234567) / 86400)?

Query zal ongetwijfeld ongeldig zijn, maar dit is het idee.

Hier staat de 1234567 voor de datum van waaraf je wilt sorteren, dus die zet je op 0; dat is bijvoorbeeld 22 juni, 00:00 uur. Nu hebben alle entries een regdate >= 0, die deel je door 86400, het aantal sec. in een dag, om de zoveelste dag van 0 te hebben. Als je dit dan afrondt op een heel getal, moet je er volgens mij iets van 0-7 uitkrijgen, waarop je groepeert, en dan ben je klaar.

Nogmaals: dit is een manier, maar of MySQL het ondersteunt, weet ik niet.

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
code:
1
2
3
4
SELECT count(*) as aantal,
         regdate,  
        (TO_DAYS(lastupdatebyuser)-TO_DAYS(now()) as dagen) FROM gebruikers
           WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 7 GROUP BY TO_DAYS(date_col)


Zou volgens mij moeten werken.

[ Voor 20% gewijzigd door beetle71 op 29-06-2003 16:01 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Ik denk dat knoeien met FROM_UNIXTIME en daaromheen weer een of andere date-extractie-functie (ala DATE_FORMAT('Ymd', FROM_UNIXTIME(regdate)) ) icm sjoorda's uitleg je een aardig eind moet helpen :)

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Nu online
Hoewel de overige suggesties allemaal best heel goed zullen werken, zie ik niet echt in waarom ze fundamenteel anders zijn dan de huidige oplossing van de topic starter; waarom zouden die wel werken en de oplossing van de topicstarter niet?

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Soultaker schreef op 29 juni 2003 @ 17:06:
waarom zouden die wel werken en de oplossing van de topicstarter niet?
sjroorda schreef op 29 juni 2003 @ 15:47:
Probleem is dat regdate een unix timestamp is, zodat verschillende tijden op dezelfde dag andere regdates zijn.
Dat lijkt me?

[ Voor 18% gewijzigd door ACM op 29-06-2003 17:20 ]


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Nu online
Ach ja, dat had ik over het hoofd gezien. Het WHERE-deel klopte wel, dus ik had verder over de groepering heen gelezen. Stom van me. |:(

Conclusie: er moet dus gegroepeerd worden op een waarde die uniek per dag is.

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Dit is een werkende oplossing:

SQL:
1
2
3
4
5
6
7
8
9
10
11
SELECT 
    count(*) as aantal, 
    ((TO_DAYS(regdate)-TO_DAYS(now()))*-1) as dagen_geleden
FROM 
    gebruikers
WHERE 
    TO_DAYS(NOW()) - TO_DAYS(regdate) <= 7 
GROUP BY
    TO_DAYS(regdate)
ORDER BY 
    dagen_geleden ASC


Waarbij je een mooi lijstje krijgt:
aantaldagen_geleden
40
71
122
113
34
55
46
217


Let wel op dat je geen resultaten krijgt voor dagen waarop niemand geregistreerd heeft

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
beetle71 schreef op 29 June 2003 @ 17:52:
Dit is een werkende oplossing:

SQL:
1
2
3
4
5
6
7
8
9
10
11
SELECT 
    count(*) as aantal, 
    ((TO_DAYS(regdate)-TO_DAYS(now()))*-1) as dagen_geleden
FROM 
    gebruikers
WHERE 
    TO_DAYS(NOW()) - TO_DAYS(regdate) <= 7 
GROUP BY
    TO_DAYS(regdate)
ORDER BY 
    dagen_geleden ASC


Waarbij je een mooi lijstje krijgt:
aantaldagen_geleden
40
71
122
113
34
55
46
217


Let wel op dat je geen resultaten krijgt voor dagen waarop niemand geregistreerd heeft
Ja die query ziet er goed uit, maar ik vat nu niet helemaal hoe ik dit moet echo'en? En hoe de array te maken.

Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
ehhh...zo bijvoorbeeld: ?
PHP:
1
2
3
4
5
6
7
8
9
10
$query = "/* wat hier boven staat */";
if ($result = mysql_query($query))
{
    while ($row = mysql_fetch_assoc($result))
    {
        echo $row['dagen_geleden']." dagen geleden was het aantal ".$row['aantal']."<br>\n";
    }
}
else
    echo $query ."<br>\nblijkt toch niet goed te zijn:<br>\n".mysql_error();

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Ja die query ziet er goed uit, maar ik vat nu niet helemaal hoe ik dit moet echo'en? En hoe de array te maken.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$qry="
SELECT 
    count(*) as aantal, 
    ((TO_DAYS(regdate)-TO_DAYS(now()))*-1) as dagen_geleden
FROM 
    gebruikers
WHERE 
    TO_DAYS(NOW()) - TO_DAYS(regdate) <= 7 
GROUP BY
    TO_DAYS(regdate)
ORDER BY 
    dagen_geleden ASC";

$result = mysql_query($qry) or die(mysql_error()); 
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))     {
echo $row['dagen_geleden']." dagen geleden registreerden ".$r['aantal']." gebruikers";
}


Bedoel je dit :? Is wel HEEL erg basic.....

edit:

Marty was sneller, maar denkt hetzelfde >:)

[ Voor 18% gewijzigd door beetle71 op 29-06-2003 19:54 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
[quote]marty schreef op 29 June 2003 @ 19:50:
ehhh...zo bijvoorbeeld: ?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?
$query = mysql_query('SELECT 
    count(*) as aantal, 
    ((TO_DAYS(regdate)-TO_DAYS(now()))*-1) as dagen_geleden
FROM 
    gebruikers
WHERE 
    TO_DAYS(NOW()) - TO_DAYS(regdate) <= 7 
GROUP BY
    TO_DAYS(regdate)
ORDER BY 
    dagen_geleden ASC
');


if ($result = mysql_query($query)) 
{ 
    while ($row = mysql_fetch_assoc($result)) 
    { 
        echo $row['dagen_geleden']." dagen geleden was het aantal ".$row['aantal']."<br>\n"; 
    } 
} 
else 
    echo $query ."<br>\nblijkt toch niet goed te zijn:<br>\n".mysql_error();

?>


Toch iets niet goed in de query, ik heb het gecontroleerd, en ik zie niets fout.
Resource id #2
blijkt toch niet goed te zijn:
You have an error in your SQL syntax near 'Resource id #2' at line 1
Tabel: gebruikers
Kolom: regdate

[ Voor 40% gewijzigd door Verwijderd op 29-06-2003 20:10 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Niemand? Sorry dat ik al kick, maar heb echt ff haast bij. Loop al de heledag te klooien.

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Mijn versie doet het bij mij zonder problemen.....

Acties:
  • 0 Henk 'm!

  • nxt
  • Registratie: November 2001
  • Laatst online: 24-08 15:34

nxt

Toch iets niet goed in de query, ik heb het gecontroleerd, en ik zie niets fout.
Tabel: gebruikers
Kolom: regdate
je doet in je laatste voorbeeld

$query = mysql_query("SELECT ....");
en vervolgens
if ($result = mysql_query($query)) ??

dus je roept de 2e keer de functie mysql_query aan met als argument het resultaat van de eerste query in plaats van een sql statement

dus als je dan die if ($result = ...) {
even veranderd in
if ($query) {

dan scheelt dat alvast weer een error

[ Voor 3% gewijzigd door nxt op 29-06-2003 22:47 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thx, ja het werkt, althans error is weg, maar output is nu niets. Ik weet zeker dat er wel data in de db staat want ik heb vandaag nog leden geregistreerd...

dag 7 tot 2 zijn leeg, geen nieuwe leden, maar gister en vandaag wel nieuwe leden, alleen hij output niets :(

zo is me scriptje nu:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
include('dbconnect2.inc.php');
$query = mysql_query('SELECT 
    count(*) as aantal, 
    ((TO_DAYS(regdate)-TO_DAYS(now()))*-1) as dagen_geleden 
FROM 
    gebruikers 
WHERE 
    TO_DAYS(NOW()) - TO_DAYS(regdate) <= 7 
GROUP BY 
    TO_DAYS(regdate) 
ORDER BY 
    dagen_geleden ASC 
'); 


if ($result = $query) 
{ 
    while ($row = mysql_fetch_assoc($result)) 
    { 
        echo $row['dagen_geleden']." dagen geleden was het aantal ".$row['aantal']."<br>\n"; 
    } 
} 
else 
    echo $query ."<br>\nblijkt toch niet goed te zijn:<br>\n".mysql_error(); 

?> 

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
echo mysql_num_rows($query); geeft 0 als waarde....

de query klopt dus niet :(

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Je hoeft niet meteen boos te worden :?
We hebben geen glazen bol om al je instellingen te kunnen zien...

Wat voor veldtype is die datum in jouw database dan?? Als ik je TopicStart nogmaals bekijk dan lijkt het op een UNIX TIMESTAMP..
Dat is niet echt de meest handige .. (bijv. datetime of timestamp zijn hiervoor beter)
Maar goed, als het inderdaad een unix timestamp is dan moet je even elke regdate in de query vervangen door FROM_UNIXTIME(regdate)

dus dan wordt je query:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$query = mysql_query('SELECT 
    count(*) as aantal, 
    ((TO_DAYS(FROM_UNIXTIME(regdate))-TO_DAYS(now()))*-1) as dagen_geleden 
FROM 
    gebruikers 
WHERE 
    TO_DAYS(NOW()) - TO_DAYS(FROM_UNIXTIME(regdate)) <= 7 
GROUP BY 
    TO_DAYS(FROM_UNIXTIME(regdate)) 
ORDER BY 
    dagen_geleden ASC 
');


Maar beter is om je veldtype te veranderen !! :)
Pagina: 1