Autor | Zpráva | ||
---|---|---|---|
Casero Profil |
#1 · Zasláno: 21. 6. 2009, 00:17:08 · Upravil/a: Casero
Dobrý večer,
dělám statistiky badmintonových zápasů, které jsou uloženy v tabulce zapasy: Struktura hrac1_id, hrac2_id, set1_hrac1,set1_hrac2,set2_hrac1,set2_hrac2,set3_hrac1,set3_hrac2 Nebo znáte lepší způsob zápisu zápasu do db? dále pak mám tabulku hraci: Struktura nick, id A snažím se vytáhnout skore každého hráče, počet zápasů atd... Samozřejmě by to šlo přes dva dotazy, první vybere hrače a druhý statistiky...ale kvůli různému seřazování statistik je to nevhodné. Ovšem můj způsob vytvoření 1 dotazu je nešikovný, jelikož nelze vytáhnout jedním poddotazem více sloupců, což je logické. Můj SQL: select h.nick, (SELECT sum(if(hrac1_id=h.id,set11+set21+set31,set12+set22+set32)) FROM `zapasy` WHERE hrac1_id=h.id or hrac2_id=h.id) as dal, (SELECT sum(if(hrac1_id=h.id,set12+set22+set32,set11+set21+set31)) FROM `zapasy` WHERE hrac1_id=h.id or hrac2_id=h.id) as dostal from hraci h order by dal A tímto způsobem bych musel stále přidávat další a další poddotaz. Proto bych se chtěl zeptat, zda existuje nějaký lepší způsob? Přemýšlel jsem o nějakém zgrupování, ale nic jsem nevymyslel, jak by to šlo provést. :( Předem mockrát děkuji za rady |
||
TomášK Profil |
#2 · Zasláno: 21. 6. 2009, 00:40:14 · Upravil/a: TomášK
Sloupce pojmenované neco1, neco2,... znamenají téměř vždy nevhodnou strukturu databáze. Nejinak v
tomhle případě. Tabulka hraci zustane (id, nick). Dál bych vytvořil tabulky zapasy(id, info o zapasu) -- tahle tabulka ani není potřeba, pokud nejsou k zápasu žádné informace sety(id, zapas_id, hrac_id, set, cislo_hrace) -- cislo_hrace je 1 pro začínajícího, 2 pro druhého Dotaz třeba na počet zápasů hráče se smrskne na: SELECT hrac_id, COUNT(*) AS pocet_zapasu FROM (SELECT hrac_id, zapas_id FROM sety GROUP BY hrac_id, zapas_id) GROUP BY hrac_id; Nelíbí se mi tam dvakrát GROUP BY, ale lepší varianta mě nenapadá. |
||
Kajman_ Profil * |
#3 · Zasláno: 22. 6. 2009, 20:36:43
Při původní struktuře by to mohlo být
select t.hrac_id, sum(t.dal) dal, sum(t.dostal) from ( (select hrac1_id hrac_id, sum(set11)+sum(set21)+sum(set31) dal, sum(set12)+sum(set22)+sum(set32) dostal from zapasy group by hrac1_id) union all (select hrac2_id hrac_id, sum(set12)+sum(set22)+sum(set32) dal, sum(set11)+sum(set21)+sum(set31) dostal from zapasy group by hrac2_id) ) t group by t.hrac_id V té nové struktuře by to šlo jedním group by díky count(distinct zapas_id). |
||
Časová prodleva: 3 dny
|
|||
Casero Profil |
#4 · Zasláno: 25. 6. 2009, 21:18:27
TomášK
Tato nová struktura vypadá chytře no. Jako kolik bodů dal je snadné, ale kolik dostal je celkem fuška. Najit ty správné protějšky. :( Kajman_ Děkuji. Pěkné. :) Ale asi ta nová struktura je krok kupředu. |
||
Kajman_ Profil * |
#5 · Zasláno: 25. 6. 2009, 23:02:09
Co udělat ty sety jako
id_zapasu, cislo_setu, body1, body2 a zápasy jako id_zapasu, hrac1, hrac2, datum a tak Union my mohl být na statistiky rychlejší než join k hledání bodů soupeře ve stejném setu, ale to jen jen domněnka. |
||
TomášK Profil |
#6 · Zasláno: 26. 6. 2009, 03:11:56 · Upravil/a: TomášK
Casero
Možná ne až tak strašná jak na pohled vypadá (v návrhu jsem zapomněl sloupec body): SELECT hrac_id, SUM(sety > sety_soupere) AS pocet_vyher SUM(sety < sety_soupere) AS pocet_proher SUM(sety) AS pocet_vyhranych_setu SUM(sety_soupere) AS pocet_prohranych_setu FROM ( SELECT hrac_id, SUM(sety1.body > sety2.body) AS sety SUM(sety1.body < sety2.body) AS sety_soupere FROM sety AS sety1 JOIN sety AS sety2 ON sety1.zapas_id = sety2.zapas_id AND sety1.set = sety2.set AND idsety1.cislo_hrace != sety2.cislo_hrace GROUP BY hrac_id, zapas_id ) AS duely GROUP BY hrac_id Kajman_ Pokud jde o rychlost, pak nedokážu odhadnout. Pokud jde o složitost dotazů, pak si myslím, že při mé struktuře budou většinou jednodušší. Mám pocit, že při tvé struktuře budou dotazy plné hrac1 = 42 OR hrac2 = 42 a UNIONu, které budou využívat ten samý kód jen s 2 místo 1. Ale pokud by se to ukázalo jako významně rychlejší, asi by to za to stálo. Jen pro představu - využívám podobnou strukturu, jako jsem popsal, jen zápasy nejsou rozdělené na sety - každý z hráčů uhraje v zápase určitý počet bodů. Dotaz na největší vítězství (nejvyšší rozdíl bodů v zápase) trvá při cca 50 000 zápasech několik sekund. Předpokládám, že výhledově přejdu na databázi, která umí indexy nad funkcemi (pokud nezjistím, že to MySQL už umí/bude umět), což by ten dotaz zřejmě zkrátilo na několik ms. Edit: doplnil jsem podmínky do JOINu, dík za upozornění |
||
Kajman_ Profil * |
#7 · Zasláno: 26. 6. 2009, 08:44:36
Ve spojení setů ješte chybí zapas_id a set. V téhle struktuře bych se možná přiklonik k redundatním údajům. Rovnou příznak přidat 0,1, zda set či zápas vyhrál. Nebudou se muset dělat porovnání < > a bude stačit sum, nebou cont-sum... a vlastně se ani nebudou muset hledat soupeři (pokud se nebude hledat součet míčků soupeřů), takže by to mohlo významně pomoci serveru.
|
||
Časová prodleva: 5 dní
|
|||
Casero Profil |
#8 · Zasláno: 1. 7. 2009, 00:07:29
TomášK
Naprosto nádherné. Hned si s tím jdu hrát. Mockrát děkuji. Kajman_ Také mockrát děkuji. |
||
Časová prodleva: 15 let
|
Toto téma je uzamčeno. Odpověď nelze zaslat.
0