Generovaní nejen fotbalové tabulky

/ Blog / PHP / Generovaní nejen fotbalové tabulky

Publikováno v sekci PHP v 13. 1. 2008 - 19:48

V tomto článku si ukážeme jak generovat fotbalovou tabulku. S menšimi úpravami můžeme samozřejme generovat nejenom fotbalovou tabulku ale i tabulku z dalších sportovních odvětví.

 1: if(isset($_POST['do'])) 
 2: {
 3: 
 4:     if($_POST['b1']==$_POST['b2']) { //remiza
 5:     mysql_query("UPDATE tabulka SET r=r+1, gf = gf+$_POST[b1], ga = ga+$_POST[b2], pz=pz+1, body=body+1 WHERE id = '$_POST[1]'");   //prvni
 6: 
 7:     mysql_query("UPDATE tabulka SET r=r+1, gf = gf+$_POST[b1], ga = ga+$_POST[b2], pz=pz+1, body=body+1 WHERE id = '$_POST[2]'"); //druhy
 8:         
 9:     } elseif($_POST['b1']<$_POST['b2']) { //vyhral b2
10:     
11:   mysql_query("UPDATE tabulka SET p=p+1, gf = gf+$_POST[b1], ga = ga+$_POST[b2],pz=pz+1 WHERE id = '$_POST[1]'");   //prvni
12: 
13:     mysql_query("UPDATE tabulka SET v=v+1, gf = gf+$_POST[b2], ga = ga+$_POST[b1], pz=pz+1, body=body+3 WHERE id = '$_POST[2]'"); //druhy   
14:     
15:     } elseif($_POST['b1']>$_POST['b2']) { //vyhral b1
16:     
17:     mysql_query("UPDATE tabulka SET v=v+1, gf = gf+$_POST[b1], ga = ga+$_POST[b2], pz=pz+1, body=body+3 WHERE id = $_POST[1]"); //prvni
18: 
19:     mysql_query("UPDATE tabulka SET p=p+1, gf = gf+$_POST[b2], ga = ga+$_POST[b1], pz=pz+1 WHERE id = $_POST[2]"); //druhy      
20: }
21: }
22: 

Výhodou: je velmi rychlý výběr z DB

Nevýhodou: může být oprava údajů. Budeme si muset vytvořit další formulář a zpracující skript, který by nám zpětně odmazal / upravil data. Je to spousty zbytečného skriptovaní navíc.

Způsob číslo 2

Tento způsob spočívá v tom, že si vytáhnem z databáze všechny odehrané zápasy, poukládáme si data do pole ( rozhodovacími mechanismy zjistíme kdo měl kolik výher, remíz, proher atd. ) a výsledné pole zapíšeme do databáze za jednotlivé týmy.

  1: function reCount()
  2:   {
  3:      $sql = "SELECT d_tym, h_tym, d_goly, h_goly, kontumace, trest1, trest2
  4:              FROM vysledky 
  5:              WHERE schvaleno = 2
  6:              AND id_souteze = $this->soutezID";
  7: 
  8: 
  9:              
 10:      $msql = mq($sql);
 11:      if (mnr($msql))
 12:      {
 13:         // inicializace
 14:         $this->init(&$data);
 15:         
 16:         while ($r = mfo($msql))
 17:         {
 18:           // nastaveni promennych
 19:           $domaci = $r->d_tym;
 20:           $hoste  = $r->h_tym;
 21:           $g1     = $r->d_goly;
 22:           $g2     = $r->h_goly;
 23:           $kontumace = $r->kontumace;
 24:           $trest1 = $r->trest1;
 25:           $trest2 = $r->trest2;
 26:           
 27:           // vypocet
 28:           
 29:           // domaci vyhrali
 30:           if ($g1 > $g2 && $kontumace != 3)
 31:           {
 32:             // nastavime domaci
 33:             $data[$domaci]["pz"]++;
 34:             $data[$domaci]["v"]++;
 35:             //$data[$domaci]["r"]++;
 36:             //$data[$domaci]["p"]++;
 37:             $data[$domaci]["gf"] += $g1;
 38:             $data[$domaci]["ga"] += $g2;
 39:             $data[$domaci]["pts"] += 3;
 40:             $data[$domaci]["trest"] += $trest1;
 41:             
 42:             // nastavime hosty
 43:             $data[$hoste]["pz"]++;
 44:             //$data[$hoste]["v"]++;
 45:             //$data[$hoste]["r"]++;
 46:             $data[$hoste]["p"]++;
 47:             $data[$hoste]["gf"] += $g2;
 48:             $data[$hoste]["ga"] += $g1;
 49:             //$data[$hoste]["pts"] += 3;
 50:             $data[$hoste]["trest"] += $trest2;
 51:             
 52:           }
 53:          // vyhrali hoste 
 54:          elseif ($g1 < $g2 && $kontumace != 3)
 55:          {
 56:             // nastavime domaci
 57:             $data[$domaci]["pz"]++;
 58:             //$data[$domaci]["v"]++;
 59:             //$data[$domaci]["r"]++;
 60:             $data[$domaci]["p"]++;
 61:             $data[$domaci]["gf"] += $g1;
 62:             $data[$domaci]["ga"] += $g2;
 63:             //$data[$domaci]["pts"] += 3;
 64:             $data[$domaci]["trest"] += $trest1;
 65:             
 66:             // nastavime hosty
 67:             $data[$hoste]["pz"]++;
 68:             $data[$hoste]["v"]++;
 69:             //$data[$hoste]["r"]++;
 70:             //$data[$hoste]["p"]++;
 71:             $data[$hoste]["gf"] += $g2;
 72:             $data[$hoste]["ga"] += $g1;
 73:             $data[$hoste]["pts"] += 3; 
 74:             $data[$hoste]["trest"] += $trest2;        
 75:          } 
 76:         // remiza 
 77:         elseif ($g1 == $g2 &&  $kontumace != 3)
 78:         {
 79:             // nastavime domaci
 80:             $data[$domaci]["pz"]++;
 81:             //$data[$domaci]["v"]++;
 82:             $data[$domaci]["r"]++;
 83:             //$data[$domaci]["p"]++;
 84:             $data[$domaci]["gf"] += $g1;
 85:             $data[$domaci]["ga"] += $g2;
 86:             $data[$domaci]["pts"] += 1;
 87:             $data[$domaci]["trest"] += $trest1;
 88:             
 89:             // nastavime hosty
 90:             $data[$hoste]["pz"]++;
 91:             //$data[$hoste]["v"]++;
 92:             $data[$hoste]["r"]++;
 93:             //$data[$hoste]["p"]++;
 94:             $data[$hoste]["gf"] += $g2;
 95:             $data[$hoste]["ga"] += $g1;
 96:             $data[$hoste]["pts"] += 1; 
 97:             $data[$hoste]["trest"] += $trest2;                
 98:         }
 99:         // kontumace pro oba 
100:         elseif ($g1 == $g2 &&  $kontumace == 3)
101:         {
102:             // nastavime domaci
103:             $data[$domaci]["pz"]++;
104:             //$data[$domaci]["v"]++;
105:             //$data[$domaci]["r"]++;
106:             $data[$domaci]["p"]++;
107:             $data[$domaci]["gf"] += 0;
108:             $data[$domaci]["ga"] += 3;
109:             //$data[$domaci]["pts"] += 1;
110:             $data[$domaci]["trest"] += $trest1;
111:             
112:             // nastavime hosty
113:             $data[$hoste]["pz"]++;
114:             //$data[$hoste]["v"]++;
115:             //$data[$hoste]["r"]++;
116:             $data[$hoste]["p"]++;
117:             $data[$hoste]["gf"] += 0;
118:             $data[$hoste]["ga"] += 3;
119:             //$data[$hoste]["pts"] += 1;
120:             $data[$hoste]["trest"] += $trest2;               
121:         }        
122:           
123:       } // while end
124:     } // numrows > 0 ?
125:   
126: 
127:   
128:   
129:   } 
130: 
131:  function insertData($data)
132:   {
133:      if (is_array($data))
134:      {
135:        foreach ($data as $tymID => $pole)
136:        {
137:          $ins  = "INSERT INTO tabulka_poradi SET ";
138:          $ins .= " id_tymu = $tymID,
139:                    kolo = $this->round,
140:                    id_souteze = $this->soutezID,
141:                    pz = '{$data[$tymID]["pz"]}',
142:                    v = '{$data[$tymID]["v"]}',
143:                    r = '{$data[$tymID]["r"]}',
144:                    p = '{$data[$tymID]["p"]}',
145:                    gf = '{$data[$tymID]["gf"]}',
146:                    ga = '{$data[$tymID]["ga"]}',
147:                    pts = '{$data[$tymID]["pts"]}',
148:                    trest = '{$data[$tymID]["trest"]}'
149:                  ";
150:          
151:          //echo $ins . "<br />";
152:          $ins = mq($ins);    
153:          //echo mysql_error();     
154:        }
155:      }
156:   }
157: 

Výhoda: pořád se jedná o velmi rychlý počin a pokud se stane , že bychom nějaký zápas zrušili nebo mu potřebovali upravit výsledek, není nic jednoduššího než tabulku z DB vymazat a znovu ji přegenerovat.

Nevýhoda: pokud se bude jednat o větší množství zápasů ( tisíce položek), netuším co to udělá s pamětí, může dojít k alokaci paměti a shození stránky. Ja jsem generovával vždy několik desítek či stovek zápasů a neměl jsem problém. Další nevýhodu vidím v tom, že pokud si budete chtít tabulku zobrazovat po jednotlivých kolech, budete Vám databáze nepřijemně narůstat.

<

h4>Způsob číslo 3

Všechno za Vás vyreší databáze

 1: SELECT
 2: ts.nazev, ts.seo_nazev,
 3: tym,
 4: SUM(W) + SUM(R) + SUM(P) as zapasy,
 5: SUM(W) as vyhry,
 6: SUM(R) as remizy,
 7: SUM(P) as prohry,
 8: SUM(G1) as goly_vstrelene,
 9: SUM(G2) as goly_obdrzene,
10: SUM(G1) - SUM(G2) as rozdil,
11: SUM(W) * 3  + SUM(R) * 1 as body
12: 
13: FROM
14: 
15: (
16: 
17: 
18: SELECT id_domaci AS tym, SUM(
19: IF (
20: g1 > g2, 1, 0
21: ) ) AS W, SUM(
22: IF (
23: g1 = g2, 1, 0
24: ) ) AS R, SUM(
25: IF (
26: g1 < g2, 1, 0
27: ) ) AS P, SUM( g1 ) AS G1, SUM( g2 ) AS G2
28: FROM vysledky
29: WHERE schvaleno = '1'
30: AND kolo <= $kolo
31: AND id_souteze = $soutez
32: GROUP BY tym
33: 
34: UNION ALL
35: 
36: SELECT id_hoste AS tym, SUM(
37: IF (
38: g1 < g2, 1, 0
39: ) ) AS W, SUM(
40: IF (
41: g1 = g2, 1, 0
42: ) ) AS R, SUM(
43: IF (
44: g1 > g2, 1, 0
45: ) ) AS P, SUM( g2 ) AS G1, SUM( g1 ) AS G2
46: FROM vysledky
47: WHERE schvaleno = '1'
48: AND kolo <= $kolo
49: AND id_souteze = $soutez
50: GROUP BY tym
51: 
52: ) TMP
53: 
54: 
55: JOIN  seznam_tymu as ts
56: ON ts.ID = TMP.tym
57: GROUP BY tym
58: ORDER BY body DESC, rozdil  DESC, goly_vstrelene DESC, zapasy DESC, nazev ASC
59: 

<

p>Výhoda: vše reší tento náročnější SQL dotaz. Neni složitý, jen trošku delší na napsání. Tímto vykreslíme tabulku do konkretního kola a není problém si zobrazit údaje z jiného kola. Pokud potřebujeme opravit zápas, opravujeme ho pouze v konkretní tabulce zápasu a o výsledné zobrazení se nestaráme. Takže časová úspora je myslím zřejmá.

Nevýhoda: bude v tom, že se bude databázový server více namáhat, než kdyby pouze tahal připravená data. On je musí počítat, setřídit a předložit. Pokud tabulku dobře osázíte indexy a těch zápasů tam nebudou tisíce ( žiju v domnění, že zobrazujeme tabulku z konkretní sézony kde proběhlo pár desítek či stovek zápasů), tak se nemusíme bát. Mám ješte složitejší dotaz, pospojováno více tabulek dohromady a výsledky jsou velmi slušné, rychlost je vždy kolem 0,005 s.

Sami si zvolte způsob, který se Vám nejvíce líbí. Tento článek není návodem, který pomocí copy & paste uvedete v pochod. Pokud znáte jiný způsob generování, vyjádřete se do komentáře.

Kategorie

  • Osobní názory - 1x
  • PHP - 9x
  • MYSQL - 4x
  • CSS - 7x
  • jQuery - 3x
  • Sociální síť - 1x
  • Nette - 5x
  • Tipy & triky - 3x
  • Twitter Bootstrap - 1x
  • Týdenní tipy a novinky - 4x
  • SCSS - 1x
  • GIT - 1x
  • Gulp - 1x

  • Komentáře (29x)

    #1 reagovat Fery:
    Zdravim, je ten 3. způsob funkční? Pokoušel jsem se ho s malými úpravy aplikovat a nějak se mi nedaří. Díky
    #2 reagovat Fery:
    Aha, jsem tupec, nic :)
    #3 reagovat Roman janko:
    [2] Fery Mel by byt funkcni, je to jeden z typu dotazu, ktere pouzivam na svych sportovnich webech. Urcite ale neslouzi k tomu, aby ho nekdo past do phpmyadminu a pak se divil ze nefunguje. Kazdy si ho musi "ohnout" sam do sveho systemu, je to spise takove zamysleni a ukazka. Ale melo by to fungovat :)
    #4 reagovat Fery:
    Jj, funguje, udělal jsem tam školáckou chybu,nevypsal si mysql_error() a divil se jak puk, proč mi to nejde. Jinak díky, hodně mi pomohl tvůj příklad :)
    #5 reagovat kubyk:
    ale romane, jaktoze tam nenapises dik cloveku, kterej ti musel vysvetlit zaklady celyho tohodle procesu co? :) Jaktoze furt na tebe nekde narazim, at vlezu do jakykoliv diskuze, zase narazim na tebe :)
    #6 reagovat Roman Janko:
    [5] kubyk Jakej kubyk? :) ( Znam 3x )
    #7 reagovat harry:
    Měl bych dotaz, dá se u toho posledního příkladu nějak omezit, aby to vypsalo můj tým (takže např. tým s id 1) a k tomu 3 týmy nad ním a 3 týmy pod ním? Díky
    #8 reagovat Roman Janko:
    [7] harry Samozrejme

    Viz. http://eldragon.pesonline.cz/statistiky/detail-tymu/4/1/

    nebo http://www.pesonline.cz/statistika/tym-v-sezone/tym-1017/s-903/r-1/?pid=903

    Nejsnazsi reseni je v aplikacni vrstve (cili v PHP) , ulozit radky do pole kde je klicem id tymu , pote si zjistit jeho pozici a jednoduchymi podminkami zajistit aby se zobrazily tymy pod nim a nad nim, v pripade ze je posledni ci prvni tak pouze nad nim resp pod nim.
    Zdravim, chtěl bych poprosit o pomoc, už mě nebaví ručně zapisovat do tabulek, byl by někdo ochoten mě spravit autonatickej zápis+odehrane zápasy, stále se mě to nedaří tak hledám pomoc, tady je ukazka tabulek NHL http://nhlsezonahraonline.717.cz/menu/uvod
    #10 reagovat Smoula:
    Ahoj, vedel by si pomoct zo zadavanim vysledkov na cele kolo nie po jednotlivych zapasoch?

    Vyberies kolo -> zapises vysledky naraz -> INSERTnes table..
    Ď.
    #11 reagovat Roman Janko:
    [10] Smoula Ano, samozřejmě. Jednotlivé inputy ponesou název pole. Tj.

    [code]

    A poté projdeš post POLE a uložíš

    foreach ($_POST["gol1"] ...)
    [/code]
    [11] Roman Janko

    Ahoj, mne sa paci ta 2.varianta - vytiahnes z DB aktualne zapasy, zadas vysledky a potom POSTnes, len nejako mi ten script nejde rozbehat :(
    #13 reagovat Roman Janko:
    [12] Smoula Je to takový nástin, jak by to mohlo fungovat, vyjal jsem to jako torzo ze svého fotbalového webu.

    Pokud máš nějaké základy v PHP tak to dáš dokupy, pokud ne, tak se PHP nejdřív trošku nauč, stejně bys později nevěděl složitejší věci i kdybych Ti s tímto pomohl.

    :-)
    .. sak to ze si to len "vyjal"... neboj zaklady mam dobre len ma zaujala tvoja 2.varianta na mojej stranke mam tiez aktualizaciu vysledkov, len trosku zlozitejsiu...

    Ale ok.. idem sa potrapit :)
    #15 reagovat Roman Janko:
    [14] Smoula Když nebudeš vědět něco konkrétního, klidně se zeptej, ale neptej se na celý skript :)
    čaute...prosim vas ja by som velmi potreboval poradit s tou tretou variaciou tabulky....tam ju musim aj prepisat nejako alebo co???? nechapem tomu bol by som velmi vdacni autorovi alebo aj hocikomu inemu co by mi to vysvetlil dakujem
    [16] Juraj To je ukázka jak vyrobit tabulku pomocí 1 SQL dotazu za předpokladu, že máš MySQL tabulku takto navrženou.
    čau nemohol by si mi spraviť tú tabulku ? pls to čo si tam napiasl som nepochopil ani jednu vec
    čau nemohol by si mi spraviť tú tabulku ? pls to čo si tam napiasl som nepochopil ani jednu vec
    [19] Erik Nevím jakou tabulku, a pokud se takto ptáš tak skutečně nemohl, protože nemáš páru o čem se zde mluví.
    Chtel bych se zeptat..co znamenají funkce mq(); mnr() a mfo() ??

    $msql = mq($sql);
    if (mnr($msql))
    {
    // inicializace
    $this->init(&$data);

    while ($r = mfo($msql))
    [21] Vasek To jsou zkratky pro mysql_query, mysql_num_rows a mysql_fetch_object ...

    Měl jsem dřívě nekolik takovýchto obalových funkcí pro jednodušší psaní.

    V dnešní době bych doporučil nějaký DB layer, například DIBI http://dibiphp.com/
    Díky za odpověď :) já používám PDO..

    chtěl bych se ještě zeptat, jak funguje inicializace $this->init(&$data); protože pak se s tou proměnnou $data hodně pracuje a myslim, že je tam tenhle část kodu dost podstatnej. Popř. jestli k tomu existuje nějakej jinej ekvivalent. Díky ;)
    [23] Vasek init funkce funguje tak, že si nastavím nulové hodnoty, pro případ, že by tým ještě nevyhrál / neprohrál / nedal gól atd.

    A parametr & tam mám proto, že jsem byl líný si ta data vracet pomocí return, jinak to žádný zvláštní důvod nemá.
    fungovalo by místo toho init i $data=0; ?
    [25] Vasek Nešlo , vypadá to takto
    http://rjwebdesign.cz/init.phps
    moc díky, už to chápu...myslel jsem si, že je to nějaká vestavěná php funkce :D
    Čau, nakonec jsem použil to 3. řešení. Potřeboval bych ale ještě jednu věc. Po skončení sezony chci aby např. nejlepší 3 týmy postoupily do LM apod...Tudíž potřebuju zjistit např. první 3 záznamy a potom 4-6 záznamy (Evropská liga) ... a nejhorší dva (sestup).
    Neptám se jak to udělat celý řešení, to vim :D, jen mě nenapadlo, že určit pořadí týmů bude takovej problém. První 3 získám snad pomocí LIMIT, poslední tři dejme tomu, když obrátim pořadí taky (i když bych nerad ten sql dotaz pouštěl 2x), ale to 4-6 ...
    #29 reagovat Roman Janko:
    [28] Vasek Pomůže Tihttp://diskuse.jakpsatweb.cz/?action=vthread&forum=28&topic=37836#cislovani-radku
    Očíslujes si řádky a dalším nadrazenym dotazem si vyberes týmy na konkretní pozici.

    Vložit nový komentář


    • na jiné komentáře odkazujte pomocí odkazu reagovat
    • vaše IP adresa bude zaznamenána
    • používají se gravatary
    • můžeme si tykat
    • HTML tagy vypnuty. PHP kód se také neprovede. Pokud potřebuju přiložit ukázku vašeho kódu, použijete službu pastebin
    • vulgární, rasistické či jinak nepřípustné komentáře budou smazány