Autor Zpráva
martinix06
Profil
Ahoj lidi. Potřebuji poradit, ať to vymýšlím, jak vymýšlím, tak se nedaří a nemůžu přijít na funkční řešení v PHP a MySQL.

Takže mám v tabulce "vysledky" sloupce "id", "vysledek". V tabulce "bodovy_system" mám sloupce "poradi", "body".

Potřebuji vypsat všechny záznamy z tabulky vysledky seřazené dle "vysledek" a vždy k nim přiřadit nějakou proměnnou pořadí a příslušné body dle pořadí z tabulky bodovy_system. Problém je ten, že "vysledek" může být několikrát stejný, například (pořadí - výsledek - body); pořadí není nikde definováno, mělo by se generovat selectem, order by vysledek:
1. - 50 - 1000
2. - 40 - 900
3. - 40 - 800
4. - 30 - 700
5. - 20 - 600
6. - 20 - 500
7. - 20 - 400
8. - 15 - 300
9. - 10 - 200
jistě jednoduše docílím tohoto výpisu, ale já potřebuji, aby ty stejné hodnoty (vysledek) měli stejné pořadí a průměr bodů (viz níže asi pochopíte):
1. - 50 - 1000
2. - 40 - 850
2. - 40 - 850
4. - 30 - 700
5. - 20 - 500
5. - 20 - 500
5. - 20 - 500
8. - 15 - 300
9. - 10 - 200

Snad jsem to vysvětlil dostatečně. Prosím o pomoc, radu, jak toto udělat v php a mysql. Zkoušel jsem toho už moc a došly nápady :D Určitě to bude triviální záležitost, ale prostě už mi to hlava nebere...

Předem děkuji za ukázky nebo rady...


Jinak jen upřesňuji, že potřebuji sestavit základní kód, ve skutečnosti jsou tabulky mnohem obsáhlejší. Tento dotaz jsem velmi zjednodušil, abychom našli co nejjednodušší řešení.

Velice děkuji, pokud někdo pomůže...
lionel messi
Profil
Veľmi som to neštudoval, nie som až taký expert, ale Některé časteji řešené dotazy pro MySQL - FAQ » "Setřepání" sloupce prípadne Poradi radku - ocislovat - slozitejsi by nepomohol? Ospravedlňujem sa, ak je to od veci.
martinix06
Profil
lionel messi:
Ale asi se to nějak z toho dá vyčíst, ale už mi to fakt nemyslí, potřeboval bych napsat vyloženě ten kód přímo na tento případ.. Ale děkuji, pokud nikdo nepomůže, tak stejně budu muset myslet a vyzkoušet i tyto rady ;)
martinix06
Profil
Takhle to vyselectím a zobrazím normálně dle prvního příkladu:

$vys=mysql_query("select vysledky_id, vysledky_hrac, rany, stb from jts_vysledky where vysledky_rocnik=".$_GET['year']." and vysledky_turnaj=".$_GET['tournament']." order by stb DESC", $dbspojeni);
$pocet_vys=mysql_num_rows($vys);
      
for ($poc=1; $poc<=$pocet_vys; $poc++) {
list($vys_id, $vys_cgf, $vys_rany, $vys_stb)=mysql_fetch_row($vys);

// hráč
$h=mysql_query("select * from jts_hraci_rocniky where hraci_cgf=".$vys_cgf, $dbspojeni);
list($hraci_id, $hraci_prijmeni, $hraci_jmeno, $hraci_cgf, $hraci_telefon, $hraci_email, $hraci_rocnik, $hraci_kod, $hraci_pohlavi)=mysql_fetch_row($h);

$b_dot=mysql_query("select body from jts_bodovysystem_zaklad where rocnik=".$_GET['year']." and umisteni=".$poc, $dbspojeni);
list($body)=mysql_fetch_row($b_dot);
$body=number_format($body, 1, ",", " ");

echo '
<tr>
  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;"></b>'.$poc.'</b></td>
  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vys_cgf.'</td>
  <td style="border: 1px solid #000000; background-color: #FFFFFF;">'.$hraci_prijmeni.' '.$hraci_jmeno.'</td>
  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vys_stb.'</td>
  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vys_rany.'</td>
  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$body.'</td>
</tr>
';
}

Mohl by někdo upravit ten kód tak, aby odpovídal příkladu druhému, prosím?
juriad
Profil
martinix06:
Zaprvé, lze to řešit dvěma dotazy a nikoli jedním + dvěma v cyklu.

Tabulka jts_vysledky (výsledky hráčů):
vysledky_id (id výsledku)
vysledky_hrac (id hráce)
rany (počet ran)
stb (něco dalšího)
vysledky_rocnik (filtrovaní)
vysledky_turnaj (filtrování)
klíče (vysledky_id), (vysledky_hrac, vysledky_rocnik, vysledky_turnaj) určují (rany, stb)

Tabulka jts_hraci_rocniky (detaily o hráčích):
id
jmeno
prijmeni
cgf (id hrace)
telefon
email
rocnik
kod
pohlavi
Tato tabulka je nejspíš blbě navržená.
Předpokládám, že klíče jsou (id) a (cgf, rocnik), a tedy jsou tam detaily každého hráče několikrát - pro každý ročník jednou.
Je tomu skutečně tak? Neměl by být hráč selektován na základě cgf a ročníku? Pro dobré řešení je nutné identifikovat jeden jediný řádek.

Tabulka jts_bodovysystem_zaklad (nejspíš přiděluje body na základě poradí):
body
umisteni
rocnik (filtrování)
klíč (rocnik, pozice) určuje (body)

Chceš tady tabulku, kde bude (zjednodušeně): jméno hráče, jeho výsledek (stb) a počet bodů, který závisí na relativním pořadí (může být několik různých hráčů na 5. místě). Je tomu tak?


On byl docela problém dešifrovat, o co se vlastně snažíš. Původně to vypadalo, že máš v databázi jednu tabulku a její výpis se snažíš nějak ovlivnit. Ale ty máš tři a přitom ta třetí s těmi dvěmi souvisí jen hodně volně.
martinix06
Profil
juriad:
BINGO :)

Ano, je to tak, že mám tabulku výsledků, kde hráče určuje vysledky_hrac (jedinečný identifikátor)... Ostatní je celkem omáčka. Ale ano, chci a potřebuji mít pro každý ročník záznam o hráči, takže jak píšeš, je možné, že jeden hráč bude mít více záznamů pro jednotlivé ročníky... ale to je ok... vždy si vyberu konkrétní na základě jeho vysledky_hrac a vysledky_rocnik z druhé tabulky.
Zde je rozhodující "stb" pro určení pořadí...

Druhá tabulka jsou právě ty údaje o hráčích.

Třetí je pak tabulka bodů, kde je určeno pořadí a k němu bodový zisk.

A právě ses úplně přesně trefil, co potřebuji. Jen upřesním, že ten počet bodů potřebuji zprůměrovat (tzn. když budou na 5. místě 3 hráči, tak se musí sečíst body pro 5.-7. místo a každý z nich dostane třetinu. A v tabulce bude pořadí pokračovat místem 8.)...

Asi jsem se úplně správně nevyjádřil, ale tys to rozkódoval na 1 :) Stačil by mi jednoduchý příklad, abych se měl čeho chytit, protože jsem se jaksi nějak zasekl s myšlením, tak jsem to v tom prvním postu hoooodně zjednodušil...
juriad
Profil
S tím průměrem jsi to dost ztížil, ale budiž. Už jsi se potkal s databázovými spojeními (JOINy)?

Toto je dotaz, který by měl vrátit všechna data v požadovaném formátu.
Struktura tohoto dotazu je:
SELECT sloupce, závislý poddotaz
FROM tabulka1
JOIN tabulka2
JOIN poddotaz1
JOIN poddotaz2
WHERE podmínka
ty poddotaz1 a poddotaz2 by měly fungovat samostaně (můžeš otestovat), stejně tak by dotaz měl fungovat když vyhodíš závislý poddotaz (ten jen přidává sloupec body). Všechny tabulky mají aliasy, aby bylo zřejmé, z které tabulky sloupec pochází.

SELECT poradi.poradi, h.hraci_prijmeni, h.hraci_jmeno, v.stb, v.rany,
(
        SELECT SUM(b.body) / pocet.pocet
        FROM jts_bodovysystem_zaklad b
        WHERE b.rocnik = v.rocnik
                AND b.umisteni >= poradi.poradi
                AND b.umisteni < poradi.poradi + pocet.pocet
) AS body
FROM jts_vysledky v
JOIN jts_hraci_rocniky h
        ON v.vysledky_hrac = h.hraci_cfg
        AND v.vysledky_rocnik = h.hraci_rocnik
JOIN (
        SELECT v1.vysledky_id, COUNT(v2.vysledky_id) + 1 AS poradi
        FROM jts_vysledky v1
        LEFT JOIN jts_vysledky v2
                ON v1.rocnik = v2.rocnik
                AND v1.vysledky_turnaj = v2.vysledky_turnaj
                AND v2.stb > v1.stb
        GROUP BY v1.vysledky_id
) AS poradi ON v.vysledky_id = poradi.vysledky_id
JOIN (
        SELECT v1.vysledky_id, COUNT(v2.vysledky_id) AS pocet
        FROM jts_vysledky v1
        LEFT JOIN jts_vysledky v2
                ON v1.rocnik = v2.rocnik
                AND v1.vysledky_turnaj = v2.vysledky_turnaj
                AND v2.stb = v1.stb
        GROUP BY v1.vysledky_id
) AS pocet ON v.vysledky_id = pocet.vysledky_id
WHERE v.rocnik = $rocnik
AND v.vysledky_turnaj = '$turnaj'

Postupně jej rozeberu:
1) Dotaz začíná s tabulkou jts_vysledky, které je přidělen alias v. Z této tabulky se úplně na konci dotazu (první řádek) vyberou sloupce vysledky_stb a vysledne_rany.
2) Dále se k této tabulce připojí informace o hráčích - tabulka jts_hraci_rocniky. Propojení je skrze rocnik a hraci_cfg, což by mělo unikátně identifikovat záznam v hráčích.
3) Dále se připojí informace o pořadí, která je výsledkem jiného dotazu. Ten dotaz zjišťuje kolik výsledků ve stejném ročníku a turnaji je z hlediska hodnoty vysledky_stb (má ho větší) před zjišťovaným záznamem. Pořádí záznamu je pak počet předchozích + 1. Informace o pořádí je připojena přes id výsledku a je vrácena jako první sloupec.
4) Pak se použije další podobný dotaz. Liší se jen tím, že hledá počet záznamů,které mají stejnou hodnotu vysledky_stb. Tato informace bude důležitá pro určovaní bodů.
5) A na závěr se ještě dopočítá počet přidělených bodů jako součet bodů za všechny pozice, které jsou ve výsledku shodné (tady se použije jednak informace o pořadí a kolik je jich shodných). Součet bodů je vydělen počtem shodných pozic hráčů. Součet + podíl je lepší než průměr, protože když bude bodovaná jen první pozice a na prvním místě by skončili 4 hráči, chceš každému dát jen čtvrtinu, nikoli průměr, který by vycházel vždy celý. Počet bodů je navíc filtrovaný podle ročníku záznamu.
6) Během výpočtu je dotaz filtrovaný na zadaný ročník a zadaný turnaj. Výkon dotazu by šlo dost zlepšit přidáním redundantních podmínek do vnitřních dotazů; kdybys měl problém s výkonem, tak se ozvi, něco vymyslíme.

Zkus si ten dotaz spustit v nějakém nástroji (PHPMyAdmin, Adminer) a odladit chyby, které jsem tam udělal (nejspíš se některé sloupečky jmenují trochu jinak).
martinix06
Profil
juriad:
No tak to je pěkný dotaz, ale už se asi chytám :) Hned jak na to budu mít chvilku, tak se na to podívám, vyzkouším, otestuji a dám vědět, každopdně děkuji ;) Rozhodně mě to nakoplo ;))

Jinak jak píšeš s těmi 4 hráči na prvním místě, tak nebudou mít čtvrtinu bodů za první místo, ale průměr z bodů za 1.-4. místo, ale to už nebude problém ;)
juriad
Profil
martinix06:
Ale v případě, že bude bodované pouze první místo a žádné jiné, tak by měl každý dostat čtvrtinu.
Hlavní problém spojený s průměrováním je, že musíš dopředu znát počet hráčů, kteří dostali stejný počet bodů (nebo si výsledky ukládat do pole a vypisovat je po celých blocích). Tedy by bylo potreba poddotaz na řádcích 23 - 29 stejně provést. Počet bodů by se dal vytáhnout jiným dotazem a dopočítávat jejich přidělení v PHP, ale zase bys tam musel mít nějaký cyklus (který je v dotazu skrytý na řádcích 3 - 7).
Proto jsem si řekl, že to půjde vše jedním dotazem.

Hlavně si ten dotaz odlaď po částech. Tohle fakt napsat na první pokus moc nejde. Kdybys narazil na nějakou chybu, napiš.
martinix06
Profil
juriad:
Rozumím ti... Když bude stejný počet stb na 1.-4. místě, tak dostanou (1+2+3+4)/4 dobů, protože tabulka musí pokračovat místem 5.
Ale to je jen detail... Vyzkouším a uvidíme, každopádně děkuji za první myšlenku ;) Nějak to dáme dohromady :)

Mám k tomu i jiné činnosti, tak nevím, kdy zas budu mít čas na to mrknout, ale hned se tu ozvu, moc díky zatím ;)
martinix06
Profil
juriad:
Tak jsem na to chvilku našel, nějaké věci poopravil a výsledný dotaz včetně kódu pro vypsání, který skvěle funguje je tento:
<?php
   echo '
       <table cellspacing=5 cellpadding=3 align=center border=0>
         <tr>
            <td width=50 align=center style="border: 1px solid #000000; background-color: silver;"><b>Pořadí</b></td>
            <td width=100 align=center style="border: 1px solid #000000; background-color: silver;"><b>Číslo ČGF</b></td>
            <td width=250 style="border: 1px solid #000000; background-color: silver;"><b>Příjmení Jméno</b></td>
            <td width=50 align=center style="border: 1px solid #000000; background-color: silver;"><b>STB</b></td>
            <td width=50 align=center style="border: 1px solid #000000; background-color: silver;"><b>Rány</b></td>
            <td width=50 align=center style="border: 1px solid #000000; background-color: silver;"><b>Body</b></td>
         </tr>
   ';

$dotaz="
SELECT poradi.poradi, h.hraci_cgf, h.hraci_prijmeni, h.hraci_jmeno, v.stb, v.rany,
(
        SELECT SUM(b.body) / pocet.pocet
        FROM jts_bodovysystem_zaklad b
        WHERE b.rocnik = v.vysledky_rocnik
                AND b.umisteni >= poradi.poradi
                AND b.umisteni < poradi.poradi + pocet.pocet
) AS body
FROM jts_vysledky v
JOIN jts_hraci_rocniky h
        ON v.vysledky_hrac = h.hraci_cgf
        AND v.vysledky_rocnik = h.hraci_rocnik
JOIN (
        SELECT v1.vysledky_id, COUNT(v2.vysledky_id) + 1 AS poradi
        FROM jts_vysledky v1
        LEFT JOIN jts_vysledky v2
                ON v1.vysledky_rocnik = v2.vysledky_rocnik
                AND v1.vysledky_turnaj = v2.vysledky_turnaj
                AND v2.stb > v1.stb
        GROUP BY v1.vysledky_id
) AS poradi ON v.vysledky_id = poradi.vysledky_id
JOIN (
        SELECT v1.vysledky_id, COUNT(v2.vysledky_id) AS pocet
        FROM jts_vysledky v1
        LEFT JOIN jts_vysledky v2
                ON v1.vysledky_rocnik = v2.vysledky_rocnik
                AND v1.vysledky_turnaj = v2.vysledky_turnaj
                AND v2.stb = v1.stb
        GROUP BY v1.vysledky_id
) AS pocet ON v.vysledky_id = pocet.vysledky_id
WHERE v.vysledky_rocnik = ".$_GET['year']."
AND v.vysledky_turnaj = ".$_GET['tournament']."
ORDER BY v.stb DESC
";
$dot=mysql_query($dotaz, $dbspojeni);
$poc=mysql_num_rows($dot);
for ($xx=1;  $xx<=$poc; $xx++) {
   list($vysl_poradi, $vysl_hraci_cgf, $vysl_hraci_prijmeni, $vysl_hraci_jmeno, $vysl_stb, $vysl_rany, $vysl_body)=mysql_fetch_row($dot);
   $vysl_body=number_format($vysl_body, 1, ",", " ");
                  echo '
                        <tr>
                           <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;"><b>'.$vysl_poradi.'</b></td>
                           <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_hraci_cgf.'</td>
                           <td style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_hraci_prijmeni.' '.$vysl_hraci_jmeno.'</td>
                           <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_stb.'</td>
                           <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_rany.'</td>
                           <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;"><b>'.$vysl_body.'</b></td>
                        </tr>
                  ';
}
   echo '
       </table>
   ';
?>

Fantasticky jsi to poskládal na první pokus z hlavy, smekám, hodně se z toho přiučím, velice děkuji!!!

A jen takový dotaz, jak bych mohl ještě udělat, aby se při stejném pořadí toto zobrazilo pouze poprvé a pak už ne, nebo se zobrazilo něco jako jako "T".$vysl_poradi? Ale pouze u těch položek, které mají stejný počet stb a tudíž stejné pořadí?

Je to už jen maličkost, ale fakt teď nevím ;)

Jak dlouho se programování věnuješ? Koukal jsem, že informatiku studuješ, tak se dají tvé logické pochody a uvažování pochopit, já takové štěstí v letech mého studia neměl a nemohl se informatice věnovat, proto to mám jen jako koníček, tak se omlouvám, že v tom neumím tak chodit ;))
juriad
Profil
aby se při stejném pořadí toto zobrazilo pouze poprvé a pak už ne
Budeš si pamatovat, jaké umístění měl předchozí záznam. Pokud se umístění aktuálního liší, vypíšeš jej (a změníš zapamatovanou hodnotu), jinak jej nevypíšeš nebo jej vypíšeš s tím Téčkem, to záleží na tobě.
Je to podobné tomuto: Nadpis skupiny

Jak dlouho se programování věnuješ?
Počátky se datují do roku 2003, když jsem k Vánocům dostal programovatelnou kalkulačku a rok poté jsem dostal učebnici Javy. A pak v roce 2010 jsem nastoupil na Matfyz, kde jsem se skutečně naučil programovat a o programech přemýšlet, nikoli je jen kódovat podle návodů.
S PHP vlastně nemám žádnou zkušenost, napsal jsem v něm jeden zápočtový program, ale nikdy jsem ho skutečně nepoužil. PHP (a všechny webové technologie) jsem se naučil z dokumentace a poskytováním rad tady na diskusi.
Neomlouvej se, ty určitě naopak umíš něco, co já ne.
martinix06
Profil
juriad:
Tak už mi to dává smysl :) Moc děkuji za pomoc... To nevím, zda umím něco, co ty ne, ale tak vždycky jsem si nějak poradil, něco vymyslel, něco našel a předělal pro své potřeby... Snad se během zítřka dostanu ještě k této úpravě a hodím sem výsledek, aby se mohli inspirovat i ostatní ;)

Moc si Tvé pomoci vážím...


juriad:
No nic, teď jsem se s tím cyklem vůbec nechytil, už to dnes nechám být :) Snad zítra na to přijdu ;)
martinix06
Profil
juriad:
Tak jsem se na to mrknul a jak jsem předpokládal, tak je tu problémek :)

$pamet="";
for ($xx=1;  $xx<=$poc; $xx++) {
   list($vysl_poradi, $vysl_hraci_cgf, $vysl_hraci_prijmeni, $vysl_hraci_jmeno, $vysl_stb, $vysl_rany, $vysl_body)=mysql_fetch_row($dot);
   $vysl_body=number_format($vysl_body, 1, ",", " ");
   if ($vysl_poradi!=$pamet) { $vypis_pozice=$vysl_poradi; $pamet=$vysl_poradi; } else { $vypis_pozice="T".$vysl_poradi; }
      echo '
            <tr>
                  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;"><b>'.$vypis_pozice.'</b></td>
                  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_hraci_cgf.'</td>
                  <td style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_hraci_prijmeni.' '.$vysl_hraci_jmeno.'</td>
                  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_stb.'</td>
                  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_rany.'</td>
                  <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;"><b>'.$vysl_body.'</b></td>
            </tr>
      ';
}
unset($pamet);

Tímto způsobem jsem ošetřil kontrolu předchzí pozice, ale když je více stejných pozic, tak u první samozřejmě nepozná, že za ní jsou duplicity, takže vypíše např. 5 a na dalších pozicích už správně T5... Nějaký nápad? Jinak vše skvěle funguje ;))
juriad
Profil
Aha, takže ty chceš něco trošku jiného. Zobrazit hodnotu pořadí jinak v případě, že se jedná o dělené místo. Já to poprvé nepochopil.

V takovém připadě žádnou paměť nepotřebuješ. Stačí si do dotazu přidat vrácení sloupce pocet.pocet, který obsahuje počet záznamů, které mají stejné pořadí. Pak se budeš rozhodovat podle hodnoty: větší než 1 = dělené místo.
martinix06
Profil
juriad:
Ajo, to je přesně ono ;)
Takže jsem upravil první select takto:
SELECT pocet.pocet, poradi.poradi, h.hraci_cgf, h.hraci_prijmeni, h.hraci_jmeno, v.stb, v.rany,

a další kód takto:
for ($xx=1;  $xx<=$poc; $xx++) {
   list($vysl_pocet, $vysl_poradi, $vysl_hraci_cgf, $vysl_hraci_prijmeni, $vysl_hraci_jmeno, $vysl_stb, $vysl_rany, $vysl_body)=mysql_fetch_row($dot);
   $vysl_body=number_format($vysl_body, 1, ",", " ");
   if ($vysl_pocet>1) { $vypis_pozice="T".$vysl_poradi; } else { $vypis_pozice=$vysl_poradi; }
      echo '
            <tr>
              <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vypis_pozice.'</td>
               <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_hraci_cgf.'</td>
               <td style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_hraci_prijmeni.' '.$vysl_hraci_jmeno.'</td>
               <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_stb.'</td>
               <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;">'.$vysl_rany.'</td>
               <td align=center style="border: 1px solid #000000; background-color: #FFFFFF;"><b>'.$vysl_body.'</b></td>
            </tr>
      ';
}

A tak už je to přesně tak jak jsem potřeboval :) Jak říkám, nejsem až tak kovaný ani chytrý, ale snažím se ;) Fakt moc děkuji...
Dále tento výpis zapíšu do DB a dále s ním budu pracovat klasickým selectem...
Jen na konci asi budu muset zapřemýšlet a poskládat podobný dotaz na určení celkových výsledků, tohle je dílčí výsledek jednotlivého turnaje, ale z tohoto si můžu zapsat co vše budu potřebovat a tak je to správně ;))
Přesto, kdybych plaval, tak se zde přihlásím o radu, jsem rád, že jsem narazil na tak šikovného odborníka ;)

Zatím opravdu moc děkuji ;)
juriad
Profil
martinix06:
Proč chceš něco zapisovat do databáze? Přece tam již ty hodnoty máš a pro celkové výsledky můžeš sestavit podobný dotaz.
Maximálně bych si do tabulky výsledků přidal sloupec body a ty body si tam předpočítal (je vidět, že jejich výpočet je docela náročný - závisí na pořadí). Ale duplikovat jména, příjmení, dílčí pořadí a dílčí výsledky v dalši tabulce nemá smysl.
martinix06
Profil
juriad:
jj, chápu, těch turnajů je 6, tak musím jen sestavit dotaz, který mi sečte dílčí turnaje, určí jednotlivé body a pořadí pro každého hráče na každém turnaji a seřadí to podle součtu bodů. Ale uvidím, jestli nebude lepší to fakt zapsat právě kvůli složitosti. Pak bych jen pro každého sečetl body a udělal pořadí a zároveň bych měl už zapsané pořadí na jednotlivých turnajích, ještě se nad tím zamyslím... Uvidíme, jak se mi to bude líbit ;) Nechci se v tom zbytečně zamotávat, aby se mi generovali všechny ty počty na stránce, to udělám jednou v administraci a zapíšu a na webu se bude jen číst tabulka. Tak asi proto uvažuju nad zápisem než nad generováním při každém načtení stránky, jestli mi teda jako rozumíš :))
Kajman
Profil
Pokud se údaje v tabulce vysledky mění jen málokdy a není potom problém spusit přepočet, mohly by pořadí i body být předpočítané v té tabulce vysledky v nových sloupcích.

Na to přepočítání by stačily pro každý turnaj dva updaty.
martinix06
Profil
Kajman:
Souhlas, něco takového si představuji. Je asi jedno, jestli to dám do nové tabulky nebo přidám sloupce...
Kajman
Profil
S novými sloupci by aktualizace pro jeden turnaj mohla vypadat přibližně takto

SET @radek=0;

UPDATE jts_vysledky
SET    poradi = @radek := @radek + 1
WHERE  vysledky_rocnik = 2014
       AND vysledky_turnaj = 42
ORDER BY stb DESC;

UPDATE jts_vysledky x
       JOIN (SELECT v.vysledky_rocnik,
                    v.vysledky_turnaj,
                    v.stb,
                    Min(v.poradi)            minporadi,
                    Avg(Coalesce(b.body, 0)) avgbody
             FROM   jts_vysledky v
                    LEFT JOIN jts_bodovysystem_zaklad b
                           ON b.rocnik = v.vysledky_rocnik
                              AND b.umisteni = v.poradi
             WHERE  v.vysledky_rocnik = 2014
                    AND v.vysledky_turnaj = 42
             GROUP  BY v.vysledky_rocnik,
                       v.vysledky_turnaj,
                       v.stb) t
         ON x.vysledky_rocnik = t.vysledky_rocnik
            AND x.vysledky_turnaj = t.vysledky_turnaj
            AND x.stb = t.stb
SET    x.poradi = t.minporadi,
       x.body = t.avgbody;
martinix06
Profil
Takže vše funguje jak má. Teď bych ještě potřeboval dotaz (strašně v tom MySQL plavu zatím:))) na celkové pořadí:
sloupce:
 id, rocnik, turnaj, cgf, poradi, body
a v tom třeba toto:
1 | 2014 | 1 | 0700490 | T3 | 600
2 | 2014 | 2 | 0700490 | 2   | 900
3 | 2014 | 1 | 0700258 | 6   | 400
4 | 2014 | 2 | 0700258 | 4   | 570

potřebuji udělat to, aby bylo pořadí podle body, ale ty musí být sečteny pro každé cgf, které tam je vždy jednou pro jeden turnaj.
Nakonec chci vypsat asi toto:

Umístění | cgf | body(celkem) | turnaj1 | turnaj2..... (podle počtu turnajů)
1 | 0700470 | 1500 | 600 | 900.....
2 | 0700258 | 970 | 400 | 570.....

Snad je to srozumitelné :) Díky za rady ;)
Kajman
Profil
Udělejte si tři jednoduché dotazy a vygenerování tabulky proveďte v php.

select cgf, turnaj, body from jts_vysledky where rocnik=2014
To si uložte do dvojrozměrného pole v php.

select * from turnaje where rocnik=2014 order by datum
To si také uložte do pole. Použijte to ke generování turnaj1, turnaj2,...

select cgf, sum(body) celkem from jts_vysledky where rocnik=2014 order by celkem desc
To použijete pro základ řádků (druhý a třetí sloupec). První sloupec si počítejte proměnnou a zbylé sloupce s rozpisem turnajů dělejte vnořeným cyklem na základě pole z druhého dotazu - a číslo do toho sloupce získáte v poli z prvního dotazu.
martinix06
Profil
Kajman:
Udělejte si tři jednoduché dotazy a vygenerování tabulky proveďte v php.

Nevím, jestli jste pochopil, co potřebuji, tak jen upřesním. potřebuji udělat součet bodů pro každé cgf a vypsat podle těch součtů pořadí a i jednotlivá skóre.

Půjde to tak?
martinix06
Profil
Tak jsem to vyřešil ;) Nakonec to vypadá takto:
      $dot_vysl=mysql_query("
      select cgf as vysl_cgf, poradi, turnaj, sum(body) as vysl_body
      from jts_vysledky_celkove
      where rocnik=".$_GET["year"]."
      group by cgf
      order by vysl_body DESC
      ", $dbspojeni);
      $poc_vysl=mysql_num_rows($dot_vysl);
      for($v=1; $v<=$poc_vysl; $v++) {
         list ($vysl_cgf[$v], $vysl_poradi[$v], $vysl_turnaj[$v], $vysl_body[$v])=mysql_fetch_row($dot_vysl);
         $dot_hr=mysql_query("select hraci_prijmeni, hraci_jmeno from jts_hraci_rocniky where hraci_cgf=".$vysl_cgf[$v]." and hraci_rocnik=".$_GET["year"], $dbspojeni);
         list($vysl_hr_prijmeni[$v], $vysl_hr_jmeno[$v])=mysql_fetch_row($dot_hr);
      }
      $dot_tur=mysql_query("select * from jts_turnaje where rocnik=".$_GET["year"]." order by termin", $dbspojeni);
      $poc_tur=mysql_num_rows($dot_tur);
      for($t=1; $t<=$poc_tur; $t++) {
         list($tur_id[$t], $tur_nazev[$t], $tur_termin[$t], $tur_hriste[$t], $tur_koeficient[$t], $tur_rocnik[$t], $tur_close[$t])=mysql_fetch_row($dot_tur);
      }      
      echo '
         <table cellpadding="3" cellspacing="5" border="0" align="center" width="800">
            <tr>
               <td class="tlacitko" align="center"><b>Pořadí</b></td>
               <td class="tlacitko">&nbsp;<b>Hráč | Turnaj</b></td>
      ';
      for ($sl=1; $sl<=$poc_tur; $sl++) {
         echo '
               <td class="tlacitko" align="center">
                  <b>'.$tur_nazev[$sl].'</b>
               </td>      
         ';
      }
      echo '
               <td class="tlacitko" align="center"><b>Celkem</b></td>
            </tr>
      ';
      for ($rad=1; $rad<=$poc_vysl; $rad++) {
         echo '
            <tr>
               <td class="tlacitko" align="center">'.$rad.'</td>
               <td class="tlacitko">
                  &nbsp;'.$vysl_hr_prijmeni[$rad].' '.$vysl_hr_jmeno[$rad].'
               </td>
         ';
         for ($sk=1; $sk<=$poc_tur; $sk++) {
            $dot_sk=mysql_query("select body from jts_vysledky_celkove where turnaj=".$tur_id[$sk]." and cgf=".$vysl_cgf[$rad], $dbspojeni);
            list($tur_body)=mysql_fetch_row($dot_sk);
            if($tur_body=="") { $tur_body="0"; }
            $tur_body=str_replace(".", ",", $tur_body);
            echo '
               <td class="tlacitko" align="center">'.$tur_body.'</td>
            ';  
         }
         $vysl_body[$rad]=str_replace(".", ",", $vysl_body[$rad]);
         echo '
               <td class="tlacitko" align="center"><b>'.$vysl_body[$rad].'</b></td>
            </tr>
         ';
      }
      echo '
         </table>
      ';

Pokud najdete nějaké chyby, tak dejte vědět, na první pohled to funguje ;)
Kajman
Profil
Pokud budete mít dvacet hráčů a deset turnajů v ročníku, budete dělat do databáze 241 dotazů pro složení té tabulku. To není zrovna nejrychlejší. Proto jsem psal, že je lepší si ty údaje vyzobnout všechny, dát je do php asociativního pole a pak je v těch vnořených cyklech využívat. Tak sestavíte tabulku jen se třemi dotazy.
martinix06
Profil
Kajman:
Díky za rady ;)


Ještě poprosím o jednu radu, potřebuji seřadit podle počtu ran vzestupně, ale aby součet počtu ran byl pro pouze 3 nejnižší záznamy, zkusil jsem toto, ale nefunguje :(
Chybu hlásí, že nezná v1.vysledky_hrac, když místo této proměnné dosadím přímo řetězec, tak ten poddotaz funguje.

      select 
         sum(v2.rany) as vysl_rany,
         v1.vysledky_hrac,
         v1.vysledky_turnaj
      from jts_vysledky v1
      join (select v3.rany as rany
                  from jts_vysledky v3
                  where v3.rany>0 and v3.rany!='-' and v3.vysledky_hrac=v1.vysledky_hrac
                  order by rany*1 ASC
                  limit 3
                  ) v2
      order by vysl_rany ASC

Můžete mi mrknout, kde je chyba? Nějak na ni nemohu přijít :( Díky předem...
martinix06
Profil
Tak ještě jinak. Toto mi funguje tak, že sečte všechny rány a seřadí je od nejmenšího po největší, což je ok:
select sum(rany) as vysl_rany, vysledky_hrac as vysl_cgf, vysledky_turnaj as vysl_turnaj 
      from jts_vysledky
      where vysledky_rocnik=".$_GET["year"]."
      group by vysl_cgf
      order by vysl_rany ASC

A teď tam potřebuji zakomponovat poddotaz, aby vysl_rany (sum(rany)) bylo omezené na 3 nejnižší záznamy každého hráče (vysl_cgf neboli vysledky_hrac) větších než 0.

Patlám se s tím dobu, studuji, jak to napsat, ale ne a ne abych to dal dohromady. Nemá cenu tu dávat, co jsem všechno zkoušel. Asi mi hlava nebere, jak ty poddotazy fungují... PLS HELP :)))

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0