Miten olisi järkevintä toteuttaa MySQL haku kun haluisin että joka kuukauden jälkeen tulisi viiva taulukkoon esim.
1.1.05 jotain 3
2.1.05 jotain 7
--------------------------
Yhteensä: 10
--------------------------
1.2.05 jotain 1
2.2.05 jotain 2
--------------------------
Yhteensä: 3
Eli tietokannassa olisi pvm,selite,osallistuja
eli aina kun kuukausi vaihtuu niin lasketaan osallistujat yhteen ja tulostetaan esimerkin tavalla. Miten olisi helpoin/järkevin toteuttaa php:llä.
Onko kuukaudet eri kentässä? Ellei, suosittelen tällaista yksinkertaista:
$kk=explode(".",$row['pvm']); if($kk[1]=='1') { // tulostetaan // lasketaan echo "--------<br>Yhteensä: ".$summa; }
Viritin tämän idean tähän 20 sekunnissa, ehkä kaipaa vähän hiomista :)
se on date muodossa eli 2005.3.16 vai miten se nyt tarkalleen menee.
Lue tiedot tietokannasta aikajärjestyksessä ja tulosta joka kuukauden loppuun summa PHP:llä.
Jep, mutta miten katon sen että milloin kuukausi vaihtuu?
Tulostat varmaankin rivit silmukassa, joten voit joka kerta tarkistaa, onko kuukausi muuttunut edellisestä tulostuksesta. Jos on, on aika pistää väliin kuukauden yhteissumma. Ja semmoinen kuuluu myös tulostuksen loppuun.
Tein tollasen esimerkki koodin, eli katonko if lauseella kuukausi kohdan aina?
echo "<table border>"; echo "<tr><td><b>PVM</b></td><td><b>Selite</b></td><td><b>Tulos</b></td></tr>"; for ($i = 0; $i < mysql_num_rows($haku); $i++) { $pvm = mysql_result($haku, $i, "pvm"); $nimi = mysql_result($haku, $i, "nimi"); $tulos = mysql_result($haku, $i, "tulos"); tässä kohtaa? pitääkö $pvm:stä ottaa jotenkin toi 01 arvo pelkästään? echo "<tr><td>$pvm</td><td>$nimi</td><td>$tulos</td></tr>"; } echo "</table>"; echo "</body></html>";
Voihan sen tehdä ihan sql:lläkin, toimii ainakin Oraclessa. Jos demo taulussa on sarakkeet pvm,selite ja osallistuja :
PVM SELITE OSALLISTUJA 3.2.2005 muu2 2 1.2.2005 muu 1 2.1.2005 jotain2 7 1.1.2005 jotain 3
Tehdään pikkuinen sql kysely joka tekee tarvittavat rivit
-- detaljirivi select to_char(pvm ,'DD') || 0 || to_char(pvm, 'dd.mm.yyyy') ||' ' || selite || ' ' || osallistuja from demo union -- väliviiva select to_char(pvm ,'DD') || 1 || '----------' || '----------' ||'----------' from demo union -- kuukausi yhteensä rivi select to_char(pvm ,'DD') || 2 || 'Yhteensä ' || to_char(sum(osallistuja)) from demo group by to_char(pvm ,'DD') order by 1
Tulostaa :
01001.01.2005 jotain 3 01001.02.2005 muu 1 011------------------------------ 012Yhteensä 4 02002.01.2005 jotain2 7 021------------------------------ 022Yhteensä 7 03003.02.2005 muu2 2 031------------------------------ 032Yhteensä 2
Tästä sitten peset alussa olevan kuukauden (esimerkissä 01 ja 02 ) pois , samoin seuraavana olevan rivin tunnisteen (0,1 ja 2). Tabuloinnit yms hienostelut keksit varmasti itsekin.
Ei toiminu toi MySQL:ssä, ei aivot taas toimi, että miten ton saisi tohon for lauseen sisälle.
Antakaas jotain vinkkiä miten tota if lausetta kannattas lähtee rakentamaan, jotta se toimisi.
Siis MySQL:ssä voi olla jotain omia funkkareita tai syntaksi voi olla erilainen. Edelläolevan ideahan on että sql-kysely tuottaa yhden sarakkeen jossa on valmiiksi 'muotoiltuna' halutut rivit. Helppohan se on for-silmukkaan on ympätä vai mitä ?
Voi olla mutta niitä nyt en tiedä ja tuntuu jotenkin luonnollisemmalta tehdä homma noin että tulostaa sen if lauseella, mutta en osaa tehdä tota että miten if-lause tarkastaa koska kuukausi vaihtuu.
Mysql:ssä sarakkeet: pvm, selite, osallistuja.
<?php $query = "select month(pvm) as kk, pvm, selite, osallistuja from taulu"; $result = mysql_query($query); if ( isset($result) ) { while ( $tmp = mysql_fetch_assoc($result) ) { $tulos[] = $tmp; } } $laskuri = 0; foreach ( $tulos as $key=>$val ) { if ( ($key > 0) && ($tulos[$key]['kk'] != $tulos[($key - 1)]['kk']]) ) { echo "eri kuukausi & osallistujat: ".$laskuri; } else { echo "sama kuukausi"; $laskuri = $laskuri + $tulos[$key]['osallistujat']; } } ?>
Jotain tuollaista siis. Välisummat ja muut sitten vain tuohon foreach silmukan sisälle rakentaa ja vóila. Ei ole sen vaikeampaa. ;)
Foreach silmukka on muuten paaaljon nopeampi kuin mikään for, while tai do while sätös. =)
Edit: lisäsin koodiin laskennan.
Wizard kirjoitti:
Eh... ensin määrittelet $result-muuttujan ja sitten testaat onko se määritelty :) isset() suohon tosta
Wizard kirjoitti:
Foreach silmukka on muuten paaaljon nopeampi kuin mikään for, while tai do while sätös. =)
Toinen eh... Vaikka foreach on nopeampi, niin koodissasi siitä ei ole mitään hyötyä, sillä kokoat taulukon ensin while() silmukalla :)
Tässä miten itse tekisin:
<table> <?php $tmp = ''; $laskuri = 0; $sql = "SELECT DATE_FORMAT(pvm, '%m') AS kk, nimi, tulos FROM taulu ORDER BY kk"; $sql = @mysql_query($sql,$link); if($sql && mysql_num_rows($sql) > 0){ while(($r = mysql_fetch_assoc($sql)) !== false){ $laskuri += $r['tulos']; if($r['kk'] == $tmp){ echo '<tr><td>'.$r['nimi'].'</td><td>'.$r['tulos'].'</td>'; }else{ echo '<tr><td colspan="2">Yht. '.$laskuri.'</td></tr><tr><td>'.$r['nimi'].'</td><td>'.$r['tulos'].'</td>'; $laskuri = 0; } $tmp = $r['kk']; } }else{ echo 'SQL-kysely kusee tai kanta on tyhjä :)'; } ?> </table>
päästä heitettynä.
$result muuttujaa ei tule jos kysely epäonnistuu jostain syystä. Se tulee vain minulta luonnostaan, koska silloin ei tule ylimääräisiä virheilmoituksia jos sattuu palvelin sellaisia tulostamaan... ;)
Ja mitä tulee while silmukalla kokoamiseen, niin en voi tietää, että onko kysely juuri siinä kohtaa sivua missä tulostus tehdään vai onko se jossain ihan muualla ja käytetäänkö mahdollista tulosjoukkoa johonkin muuhunkin tarkoitukseen.
Nuo on käytännössä sellaisia mitkä sopii myös PHP5:n oliomalliin ja toimii niissä ilman sen kummempia...sinun versiosi ei ehkä niinkään. ;)
Wizard kirjoitti:
$result muuttujaa ei tule jos kysely epäonnistuu jostain syystä.
Väärä vastaus :) Kyllähän se tulee. Jos kysely epäonnistuu, se vain saa arvon false. Muutuujan pystyy poistamaan käsittääkseni ainoastaan unset()-funktiolla niin, ettei isset() sitä tunnista.
Miksei oma koodini toimisi php 5:ssa? Tosin en tiedä toimiiko se missään muuallakaan, koska en sitä testannut, mutta jos toimii, niin ei käsittääkseni 5-versio tuohon koodiin mitään vaikuta.
Aihe on jo aika vanha, joten et voi enää vastata siihen.