Favicon Svetmobilne.cz  Svět mobilně Favicon Svetaudia.cz  Svět audia Favicon TVFreak.cz  TV Freak   Fórum Favicon Digimanie.cz  Digimanie   Fórum   Galerie
Strana 1 z 3 123 PosledníPoslední
Zobrazené výsledky: 1 až 15 z 31

Téma: MySQL SELECT z viacerých tabuliek

  1. #1
    Občasný diskutér Avatar uživatele dabelik
    Registrace
    Feb 2009
    Příspěvků
    111

    Zdravím,

    máme MySQL script:

    "SELECT fight_enemy.nick, DATE_FORMAT(fight.time,'%D %M %Y %H:%i:%s') AS time, fight_enemy.experience AS ene_exp, fight_me.experience AS me_exp, IF(fight_me.gold = 0, (SELECT -fight_enemy.gold FROM fight_enemy WHERE fight_enemy.fight_id_fight = fight.id_fight LIMIT 1), fight_me.gold) AS gold, fight.win, fight_me.attacker FROM fight JOIN fight_enemy ON fight_enemy.fight_id_fight = fight.id_fight JOIN fight_me ON fight_me.fight_id_fight = fight.id_fight GROUP BY fight_enemy.nick ORDER BY time DESC"

    Select vyberie všetky súvisiace dáta ako potrebujem avšak vyberá prvý výskyt v DB, totiž v tabuľke fight sú informácie o čase zápasu a pod., v tabuľke fight_enemy sa nachádzajú duplicitné údaje (boj s rovnakým protivníkom) a ja by som potreboval vybrať len raz (unikátne) nick protivníka (preto som dodal GROUP BY) ale dáta z posledného boja (akosi neviem kde zahrnúť podmienku aby vybrala DB zápas, ktorý má "MAX(fight.time)"). Netuším či som to dostatočne zrozumiteľne vysvetlil ale napadá niekoho nejaké možné riešenie?

    Vopred vďaka za odpovede, s pozdravom striky..
    Odpovídat lze po přihlášení

  2. #2
    Obyvatel SHW
    Registrace
    Nov 2007
    Příspěvků
    428

    Neviem ci som spravne pochopil, ale

    pokial ti to dava spravny result set a zoradeny tak ako chces,
    tak by sa dal pouzit limit
    http://php.about.com/od/mysqlcommands/g/Limit_sql.htm

    potom by bol Limit 0,1 (0- od prveho, pocet 1)


    Inak sa to dost strasne cita .... odporucam formatovat dako takto:

    Select o.meno,o.priezvisko, p.id
    From Osoby o, Pracovnici p
    Where o.pkey = p.rc //vlastne join on ....
    AND p.id < 50000
    Order by bla bla...
    Group by bla bla...


    taktiez nie je na skodu, daka ilustracia tabuluky/tabuliek //nemusi byt cela, staci aby clovek vedel co ktora tabulka obsahuje a co ide kam ako Pkey-Fkey
    Odpovídat lze po přihlášení



  3. #3
    Občasný diskutér Avatar uživatele dabelik
    Registrace
    Feb 2009
    Příspěvků
    111

    Ahoj,

    ak ale použijem LIMIT tak mi vypíše len jeden nick, nie? Ja potrebujem každý nick iba raz, čiže ekvivalent k DISTINCT (čo v tomto selecte nefunguje).

    Schéma:

    Tab1::fight
    (PK)id_fight, time, win
    1, 2011-03-30 00:48:24, 1
    2, 2011-03-30 01:48:24, 1
    3, 2011-03-30 03:48:24, 0
    ...

    Tab2::fight_enemy
    (PK)id_enemy, (FK)fight_id_fight, nick, gold, experience
    1, 1, enemy1, 0, 0
    2, 2, enemy2, 0, 0
    3, 3, enemy1, 70, 0
    ...

    Tab3::fight_me
    (PK)id_me, (FK)fight_id_fight, nick, gold, experience
    1, 1, me, 100, 0
    2, 2, me, 50, 0
    3, 3, me, 0, 0
    ...

    Result:
    nick, time, gold, win
    enemy1, 2011-03-30 03:48:24, 100, 1 // Tu DB vyberie prvý zápas pre daný nick
    enemy2, 2011-03-30 01:48:24, 50, 1

    Miesto toho aby mi vyšlo toto:
    nick, time, gold, win
    enemy1, 2011-03-30 00:48:24, -70, 0 // Takto je to správne (posledný zápas pre daný nick)
    enemy2, 2011-03-30 01:48:24, 50, 1

    Myslím, že to už vnieslo trošku svetla do problému, prípadne sa pýtaj ďalej. Ďakujem ti za reakciu.
    Odpovídat lze po přihlášení

  4. #4
    Obyvatel SHW
    Registrace
    Nov 2007
    Příspěvků
    428

    Acha asi uz viem co mas na mysli, ... no zda sa ze sa nevyhnes /tolko nenavidenemu/ vnorenemu selectu

    takze miesto toho Order by Time desc (pokial si to planoval kvoli tomu aby nahadzovalo posledny cas - v skutocnosti to triedi az celu vyslednu mnozinu)
    -ak si to celkove triedenie planoval, tak samozrejme nechaj ....


    ale tak este ten vnoreny select v podmienke na konci ...
    WHERE time = (SELECT MAX(pomF.Time)
    FROM fight pomF
    WHERE pomF.id_enemy = xxx.id_enemy
    )
    xxx by bolo pomenovanie tabulky fight_enemy vo vonkajsom from //alias
    Odpovídat lze po přihlášení

  5. #5
    Občasný diskutér Avatar uživatele dabelik
    Registrace
    Feb 2009
    Příspěvků
    111

    Ahoj,

    ak som to správne pochopil tak by to malo vyzerať takto:
    "SELECT f_e.nick, DATE_FORMAT(f.time,'%D %M %Y %H:%i:%s') AS time, f_e.experience AS ene_exp, f_m.experience AS me_exp, IF(f_m.gold = 0, (SELECT -f_e.gold FROM fight_enemy f_e WHERE f_e.fight_id_fight = f.id_fight LIMIT 1), f_m.gold) AS gold, f.win, f_m.attacker, f_e.fight_id_fight AS test FROM fight f JOIN fight_enemy f_e ON f_e.fight_id_fight = f.id_fight JOIN fight_me f_m ON f_m.fight_id_fight = f.id_fight WHERE f.time = (SELECT MAX(pomF.time) FROM fight pomF WHERE pomF.id_fight = test) GROUP BY f_e.nick ORDER BY f.time DESC"

    Čo ale nefunguje pretože alias vo WHERE nieje ešte naplnený a použitie HAVING kvôli aliasu sa mi akosi tiež nedarí rozchodiť. Neviem čo s tým no. Ale vďaka za snahu
    Odpovídat lze po přihlášení

  6. #6
    Obyvatel SHW
    Registrace
    Nov 2007
    Příspěvků
    428

    myslel som to dako takto:

    SELECT f_e.nick, DATE_FORMAT(f.time,'%D %M %Y %H:%i:%s') AS time,
    f_e.experience AS ene_exp, f_m.experience AS me_exp,
    IF(f_m.gold = 0, (SELECT -f_e.gold FROM fight_enemy f_e WHERE f_e.fight_id_fight = f.id_fight LIMIT 1), f_m.gold) AS gold,
    f.win, f_m.attacker,

    FROM fight f
    JOIN fight_enemy f_e ON f_e.fight_id_fight = f.id_fight
    JOIN fight_me f_m ON f_m.fight_id_fight = f.id_fight

    WHERE f.time = (SELECT MAX(pomF.time) FROM fight pomF WHERE pomF.id_fight = f_e.fight_id_fight)
    GROUP BY f_e.nick
    ORDER BY f.time DESC"


    hadze to daky error ?
    Odpovídat lze po přihlášení

  7. #7
    Občasný diskutér Avatar uživatele dabelik
    Registrace
    Feb 2009
    Příspěvků
    111

    Ahoj,

    myslím, že som to už aj takto predtým skúšal a síce nevyhodí to žiaden error ale stále to selectuje ako "MIN" než "MAX" date. Myslím, že som zle navrhol databázu alebo čo, nieje možné aby to robilo takéto problémy
    Odpovídat lze po přihlášení



  8. #8
    Obyvatel SHW
    Registrace
    Nov 2007
    Příspěvků
    428

    neviem ako vyzera cela DB, no pride mi kusok "naopak"

    osobne by som robil tabulku s hracmi ...

    Player (Table)
    (PK_ID_Player)
    --------
    + jeho dalsie data


    a udaje o boji reprezentoval ako m:n vazbu medzi tablukami Player >-< Player (medzi tou istou tabulkou)
    kde by potom ako privatny kluc figuroval kompozitny key

    -------------------
    ID_player_attacker
    ID_player_victim
    timeOfFight
    -------------------
    + dodatocne data pre boj


    ----------------------------------
    este ma napada daco s kurzorom, .... najprv otazka:

    Tab2::fight_enemy
    (PK)id_enemy, (FK)fight_id_fight, nick, gold, experience
    1, 1, enemy1, 0, 0
    2, 2, enemy2, 0, 0
    3, 3, enemy1, 70, 0

    id_enemy je PK
    enemy nick nie je rovnaky pri kazdom Id_enemy ?

    lebo mam teraz nejasno, ci urcujes o akeho hraca ide len podla jeho "nick" a id_enemy je len umely private key (zrejme autoincrement)

    alebo prave platí ze id je spate s nickname, a id_enemy jednoznacne reprezentuje dakeho hraca, ... bo v takom pripade sa kazdy hrac s is_enemy moze do boja zapojit len raz
    Odpovídat lze po přihlášení

  9. #9
    Občasný diskutér Avatar uživatele dabelik
    Registrace
    Feb 2009
    Příspěvků
    111

    Tak asi bude najlepšie skúsiť popremýšľať o zmene databázy. Ale máš pravdu, id_enemy je len AI (auto_increment). Mne tie vzťahy už na škole robili problémy, stále som si to ináč vysvetlil a potom nevzniknú dostatočne efektívne tabuľky. Vďaka ti teda za rady
    Odpovídat lze po přihlášení

  10. #10
    Obyvatel SHW
    Registrace
    Nov 2007
    Příspěvků
    428

    SELECT OFE.nick
    FROM fight_enemy OFE //--Outer Fight Enemy
    WHERE OFE.id_Fight =
    (
    SELECT id_fight
    FROM Fight F, Fight_Enemy FE
    WHERE f.id_fight = fe.id_fight
    AND fe.Nick = ofe.Nick
    AND fe.time =
    (
    SELECT max(time)
    FROM Fight ff, fight_enemy ffe
    Where f.id_fight = ffe.id_fight
    And ffe.nick = OFE.nick
    )
    )


    No tak henten select (ak taku nechutnost este mozem tak pomenovat ), by ti "mal" dat ten nick co si chcel, ... vdaka tym opacnym id, sa ti to rozbija tak ako nechces, .... a kedze treba viazat z opacnej strany a podmienovat podla mena, ...

    kratko povedane vysvetlenie " zobraz nick ktory obsahuje id_fight rovny id_fightu do ktoreho sa zapojil moj nick, a ten fight ma najvyssi cas z tych do ktorych sa moj nick zapojil ..."

    dalsi neprijemny dosledok, ak vonkajsi select previazes s inou tabulkou, tak to zacne davat inaksie vysledky, lebo to zacne rozbijat, ... ak by si chcel vypisat cas boja, tak za OFE.Nick, by siel dalsi vnoreny select, kde by sa selectol time s podmienkou where(aliasFE.id_fight = OFE.fight)

    Pokial mas moznost zmenit databazu, tak ju radsej zmen, ... uz jeden vnoreny select je podla niektorych ludi prasarna kvoli degradacii vykonu, ...
    napr v Oracle odporucaju, ak uz vnoreny select, tak ho aspon napisat pomocou In, Exists //pricom sa ma clovek snazit radsej pouzit exists kvoli lepsej optimalizacii dotazu zo strany ich cost based optimalizera ...


    Co sa tyka tych vztahov, odporucam poriadne pozriet, navrh od toho zavisi,
    darmo sa tymto databazam nehovori Relacne (Relationship-vztah)
    na autoincrement pk nie je nic zle, len musí byt s niecim spojene (1PK pre jednu entitu)

    taka pomocka autoincrement je vhodny tam kde neexistuje prirodzeny privatny kluc, alebo privatny kluc tvoria mnoziny vela atributov,... vtedy je ich vhodne nahradit umelym klucom, no pri vkladani davat pozor aby nevznikla ta ista entita s dvoma klucmi ....

    pekny priklad

    Meno, priezvisko, adresa (menovcov neuvazujeme, ine udaje dostupne nemame)

    PK mozu tvorit tieto tri, no je vhodne nahradit AI

    0, jozo, mrva, brno....
    1, peter, mrva, brno...
    2, jozo, mrva, praha...
    3, jozo, mrva, brno... <------ DTB s AI to umozni, lebo su to pre neho rozne data, no prave tomuto musime zabranit, napr trigger on insert co skontroluje ci taka kombinacia uz neexistuje .....

    prajem vela zdaru
    Odpovídat lze po přihlášení

  11. #11
    Občasný diskutér
    Registrace
    Sep 2008
    Příspěvků
    69

    Pokud vezmu váš původní dotaz mohu vytvořit následující SQL:

    Select vyberie všetky súvisiace dáta ako potrebujem avšak vyberá prvý výskyt v DB, totiž v tabuľke fight sú informácie o čase zápasu a pod., v tabuľke fight_enemy sa nachádzajú duplicitné údaje (boj s rovnakým protivníkom) a ja by som potreboval vybrať len raz (unikátne) nick protivníka (preto som dodal GROUP BY) ale dáta z posledného boja (akosi neviem kde zahrnúť podmienku aby vybrala DB zápas, ktorý má "MAX(fight.time)"). Netuším či som to dostatočne zrozumiteľne vysvetlil ale napadá niekoho nejaké možné riešenie?

    1) Potřebujete unikátní nick protivníka:
    Mimo jine podle struktury tabulky unikatni nick neni, pouze unikatni ID
    Kód:
    select distinct 
         nick
        ,id_enemy 
    from fight_enemy
    2) Potrebujete k nemu dotahnout zapas s maximalnim casem, toto bude delat divne veci, pokud mohou byt dva zapasy v jednom case. Nejprve vybereme ke kazdemu id maximalni cas zapasu ... a pak zpet k maximalnimu casu vybereme id_zapasu. Ted kdyz na to koukam, tak vlastne neni potreba ani ten select distinct z predchoziho kroku, protoze tento obsahuje jednou kazde id_enemy, ktere melo nekdy zapas.
    Kód:
    select  -- vysledek je id posledniho zapasu (pokud nemohou mit 2 zapasy stejny cas) ke kazdemu id_enemy
        max_cas.id_enemy
        f.id_fight
    from fight as f
    inner join ( -- tento vnitrni select vybere ke kazdemu id_enemy maximalni cas zapasu
            select
                id_enemy
                ,max(time) as maxtime
            from fight as fi
            inner join fight_enemy as fe on (fi.fight_id_fight eq fi.fight_id)
                group by id_enemy
        ) max_cas
        on (f.time eq max_cas.max_time)
    3) A ted lze ty predchozi selecty pouzit jako zdroj pro dalsi ... nebudu to psat uz bych tam nasekal moc chyb ... pri ladeni je dobre si kazdy ten select udelat do tabulky nebo do view odladit a na konci v tom poslednim selectu dosadit misto view ten kod.


    WHERE f.time = (SELECT MAX(pomF.time) FROM fight pomF WHERE pomF.id_fight = f_e.fight_id_fight)

    Tohle by nemelo fungovat protoze v tom vnitrnim dotazu neni definovan alias f_e (mozna ze to ma mysql nejak osetrene, ale ve standardnim sql to nejde. Navic tam chybi k tomu maximu agregace (group by).

    Co se tyka struktury databaze, tak nevim co presne chcete delat, takze me ani nenapada nejaka optimalizace ... ale to co mate nevypada uplne spatne ... akorat nick a id_enemy by si asi zaslouzilo svoji vlastni tabulku.

    Pokud naspecifikujete presne co chcete a date struktury muzeme ten dotaz klidne dotvorit.

    P.S.
    darmo sa tymto databazam nehovori Relacne (Relationship-vztah)
    Relační databáze se nazývají relační, protože nad nimi lze provádět relační opearace ... neboli tabulky jsou v matematicke relaci.
    Odpovídat lze po přihlášení

  12. #12
    Občasný diskutér Avatar uživatele dabelik
    Registrace
    Feb 2009
    Příspěvků
    111

    Ahoj,

    skúsil som znovu vytvoriť návrh DB a postupoval som takto:

    1) Rozpísal som si dáta, s ktorými budem pracovať:
    - fight, time, link, win, nick, clan, gold, experience, level, fight_value, power, defense, skill, stamina, charisma, hit_chance, chance, injury, energy_btf, energy_atf, attacker

    2) Dáta rozdelil do skupín a vyšli mi tri tabuľky:
    - player => nick (PK), clan
    - player_skill => id_player_skill (PK, AI), level, fight_value, power, defense, skill, stamina, charisma, hit_chance, chance, injury, energy_btf, energy_atf
    - fight => fight (PK), time, link, win, gold, experience, attacker

    3) Určil si požiadavku na dáta:
    - zoznam zápasov pre každý nick, ktorý mal so mnou zápas usporiadaný podľa času

    4) Určil vzťahy medzi tabuľkami:
    - player - player_skill => 1:n
    - tab.1: Koľko vlastností môže mať jeden hráč? Práve jednu čiže 1.
    - tab.2: Koľko hráčov môže mať takéto skúsenosti? Viacerí čiže n.
    - player - fight => 1:n
    - tab.1: Koľko práve takých zápasov môže mať jeden hráč? Práve jeden čiže 1.
    - tab.2: Koľko hráčov môže mať práve taký zápas? Dvaja čiže n.

    5) Doplnil som FK do tabuliek na základe bodu 4.:
    - player_skill => player_nick (FK)
    - fight => player_nick (FK)

    Myslíte, že takýto návrh by mohol svižnejšie fungovať?

    Vopred vďaka za reakcie, s pozdravom striky..
    Odpovídat lze po přihlášení



  13. #13
    Občasný diskutér
    Registrace
    Sep 2008
    Příspěvků
    69

    1) No jdes na to podle me ze spatneho konce ... zkus si nejprve napsat co chces ... typu:
    Potrebuji vytvorit databazi pro hru. Hra spociva zapaseni jednotlivych hracu mezi sebou. Zapas vypada tak ze ... atd...

    Z toho si pak muzes udelat seznam co vsechno potrebujes ... prvni nastrel se dela, ze podstatne jmeno je atribut a sloveso je vztah mezi tabulkami (treba: zapas, hrac ... hraci zapasi). Podle me najdes spoustu veci na ktere bys jinak zapomnel.

    2) V bode 4 to je nejake popletene (pokud vlastnost = skill) tak player -> skill 1:n znamena ze jeden hrac muze mit nekolik skillu. Nicmene v realu to je M:N jeden hrac muze mit vice skillu jeden skill muze mit vice hracu ... resi se to vazebni tabulkou.

    3) Nektere veci nejsou jasne, tak to napisu tak jak si myslim ze to je pripadne me muzes opravit (budu pouzivat anglicke vyrazy at se to neplete).

    Tohle si myslim ze tu je napsane:
    Player ma nekolik udaju - prislusnost ke clan
    Player muze mit nekolik skill
    Player muze zapasit s jinym player to je fight
    Fight ma nekolik udaju - time, link, win, gold, experience, attacker
    Skill ma nejake vlastnosti/parametry - level, fight_value, power, defense, skill, stamina, charisma, hit_chance, chance, injury, energy_btf, energy_atf

    Tohle mi chybi:
    Clan ma nejake udaje - nazev

    Dale nevim jestli parametry skill zavisi nejak na hraci, predpokladam ze ne.

    Takze by mi z toho vychazelo - nejprve entity a atributy
    player (player_id (pk), player_name)
    skill (skill_id (pk), skill_name, parametry ....)
    fight (fight_id (pk), time, gold ...)
    clan (clan_id (pk), clan_name ...)


    Ted bych to propojil (propojovaci tabulky):
    a) hrac patri do nejakeho klanu - tady si lze zvolit cizi klic ke hraci, protoze patri prave do jednoho klanu, nebo udelat propojovaci tabulku ... dame cizi klic do tabulky player
    player (player_id (pk), player_name, clan_id (fk) )
    b) hrac ma nekolik skillu - predpoklad je, ze parametry skillu nezavisi na hraci
    zalozime tabulku player_has_skill (player_id (pk), skill_id (pk)) ta nam propoji ciselnik skillu s hraci
    c) to nejtezsi budou asi ty souboje
    zde jsou ruzne moznosti
    - bud do tabulky fight doplnit player_id kteri bojovali (zde se ale dopoustime rozliseni na prvniho a druheho player_id a to nemusi byt spravne a komplikujeme si s tim vybery)
    - vyrobime tabulku s informaci, ze se hrac ucastnil fightu player_had_fight (player_id(pk), fight_id(pk)) - nevyhoda je trosku slozitejsi dotaz, vyhoda je ze lze rozsirit system na 2 hrace.

    Dale pokud time nema zadny fyzikalni vyznam (pepa hral v 17:35) lze podle me nahradi nejakym poradovym cislem zapasu ze sekvence.

    Vazby jsou
    player - clan 1:1
    player - player_has_skill 1:N
    player_has_skill - skill N:1
    player - player_had_fight 1:N
    player_had_fight - fight N:1 (pro 2 hrace by to bylo 2:1)

    Neresim ted constrainty ty v praci nepouzivam, takze o nich nemam aktivni znalost, ale mely by osetrit ruzne veci jako, ze jednoho zapasu se ucastni 2 hraci atd. ale to lze udelat az nakonec.

    Jinak je to vymyslene na kolene uz jsem to dlouho nedelal, takze jsem toho hodne zapomnel ... u veci, ktere byly v predchozim prispevku nejednoznacne jsem si vybral nejaky vyznam. Kdyztak dovysvetli (idealne napiste slovy co to ma byt) a poresime.
    Naposledy upraveno uživatelem grafnev: 12-04-2011 v 21:04 Důvod: upravy
    Odpovídat lze po přihlášení

  14. #14
    Občasný diskutér Avatar uživatele dabelik
    Registrace
    Feb 2009
    Příspěvků
    111

    Ahoj,

    budem reagovať postupne na tvoje body..

    1) Zaujímavý poznatok o podstatných menách a slovesách (vďaka do budúcna), avšak je nutné dodať že DB je tvorená pre čisto len štatistiku z hry do ktorej "nevidím" (kódovo). Dáta získavam šikovnosťou simple_html_dom, nakoľko cieľom je vytvoriť vlastnú štatistiku bojov (sú ľudia, ktorí majú dostatok rozumu aby neplatili premium účty).

    2) Uznávam, že asi takto by to pochopil každý ale je to myslené tak, že hráč má práve také vlastnosti (jeden riadok), ktoré získam z website hry ale môže sa naskytnúť, že presne rovnaké by mal ešte ďalší hráč a preto mi vyšiel vzťah n (i keď to by chcelo obrovskú dávku náhody, kvôli percentuálnym vyjadreniam istých hráčskych vlastností).
    EDIT: Pri písaní nižšie uvedeného bodu "c)" v časti prepojenia tabuliek som si uvedomil niečo dôležité a síce to, že tie vlastnosti sa musia ukladať pre každý zápas znovu a znovu. Nakoľko štatistika bude pre každý zápas a teda keby som uložil iba raz a následne ich UPDATE-oval pre daného hráča tak by to už nesedelo lebo pre každý zápas mal daný hráč stále rovnaké hodnoty týchto vlastností. Čiže ešte aj tu bude zrejme musieť pokutovať FK od tabuľky fight.

    3) Dobrá poznámka, pozabudol som že vlastne viacerí budú môcť patriť do istého clanu takže tabuľka s clanom je dobrá pripomienka a tá bude obsahovať iba názov clanu, nič viac.

    Prejdem tie veci, ktoré si myslíš že sú:
    Player ma nekolik udaju - prislusnost ke clan => áno (nick a clan)
    Player muze mit nekolik skill => áno (ALE môže mať iba 1. riadok pre daný zápas)
    Player muze zapasit s jinym player to je fight => áno (boj sa skladá z dvoch hráčov)
    Fight ma nekolik udaju - time, link, win, gold, experience, attacker => áno (time - čas kedy bol zápas odohraný yyyy-mm-dd H:i:s, link - url z ktorého sú dáta vďaka simple vytiahnuté, win - výhra/prehra, gold - získané zlato, experience - získané skúsenosti, attacker - či som útočník ja alebo zaútočil niekto na mňa)
    Skill ma nejake vlastnosti/parametry - level, fight_value, power, defense, skill, stamina, charisma, hit_chance, chance, injury, energy_btf, energy_atf => áno (vlastnosti tvorí jeden riadok pre daného hráča a daný boj)

    Takže výsledok by bol:
    player (player_id (pk), player_name) // Mimochodom, prečo nemôže byť PK zvolený nick? Stále sa musí jednať o dátový typ Integer?
    skill (skill_id (pk), parametry ....)
    fight (fight_id (pk), time, gold ...)
    clan (clan_id (pk), clan_name ...)

    Prepojenie tabuliek:
    a) Súhlasím, to by sedelo..
    b) Tu už to nesedí nakoľko som (dúfam dobre) vysvetlil prečo nie.
    c) Potreboval by som selektovať dáta podľa toho s kým som mal zápas, resp. vyselektovať všetky zápasy pre všetkých nepriateľov a pod. takže asi by bol lepší ten druhý spôsob len či sa budú dať potom vyťahovať dobre dáta, to už netuším. Napríklad vytiahnuť pre každé enemy čo so mnou malo zápas, jediný a síce posledný zápas (podľa time) a k nemu všetky súvisiace údaje (aké mal u daného zápasu, daný hráč vlastnosti/player_skill).

    Myslím, že som sa v tom trošku zamotal a som unavený tak ak som to ešte viac poplietol tak mi povedz a zajtra to zbúcham do zrozumiteľnejšieho jazyka

    Ďakujem ti za tvoju snahu, s pozdravom dabelik..
    Naposledy upraveno uživatelem dabelik: 12-04-2011 v 23:24
    Odpovídat lze po přihlášení

  15. #15
    Občasný diskutér
    Registrace
    Sep 2008
    Příspěvků
    69

    Aha, myslim si ze jsem nepochopil toto:

    Ja jsem bral skill jako dovednost ... tzn. napr. veci jako double kick, fireball apod. ... ale ty beres asi skill jako vlastnost ... tzn. sila, brneni atd.

    Z toho plyne: Bod 2) To ze by nahodou nekdo mel stejne hodnoty bych vubec neresil, proste kazdy hrac ma svuj radek informaci o parametrech.

    Pokud vezmu skilly timto zpusobem (tj. sila, brneni, zivoty), tyto udaje se ale meni zapas od zapasu.
    Takze nejjednodussi (a nejmene elegantni) reseni je to priplacnout k player_had_fight, na tuto situaci se to asi hodi, protoze kdyz budes potrebovat dalsi vlastnost tak proste pridas dalsi radek. Mozna se ty zaznamy o vlastnostech nebudou moc lisit, ale to neva pro takovy ucel. Nevyhoda je, ze nemuzes mit zaznamenane skilly pro hrace, ktery nikdy nebojoval je to takove neciste reseni.
    player_had_fight(fight_id(pk), player_id(pk), parametry skillu)

    Protoze delas vicemene nejake chytrejsi udelatko z nejake hry tak podle zkusenosti co mam je dobre se vydat co nejjednodussi cestou bez ohledu na to jak ta dabaze pak bude nehezka.
    Jine by to bylo, kdybys to pak chtel pouzivat dale a rozsirovat, pak je dobre venovat navrhu vetsi pozornost.


    Ad bod c) Pokud ty udaje dobre pospojujes a promitnes tam vsechny vlastnosti a vazby tak jak jsou ve skutecnosti muzes provest dotaz na vsechno. Rozhodne bych ale nijak ve strukture nerozlisoval tebe a ostatni ... to se udela az pak pri vyberu.


    Az budes delat nejaky dotaz, tak si ho take napred naformuluj slovne, pak ho rozhod na kousky a pak naprogramuj.
    Priklad:
    chci vypsat vsechny me posledni zapasy pro kazdeho soupere se kterym jsem bojoval.

    Vidim tam: Vsechny me zapasy
    Vidim tam: Posledni zapasy
    Takze kdyz vsechny me zapasy spojim s poslednimi zapasy budu mit vysledek.

    Pozn. A tady vidim nedokonalost toho co jsem navrhl, pri pripojovani hracu a zapasu si musim davat pozor abych nepripojil sam sebe, respektive stejneho hrace. U zapasu 2 hracu proti sobe to je v pohode, kdyz jich bude vice budu mit problem: Pokud spolu budou najednou bojovat hraci A, B, C tak pri propojeni dostanu dvojice AB AC BC.


    Kód:
    select
        p1.player_id as player1
        ,p2.player_id as player2
        ,p1.fight_id
        ,f.*
    -- Takze nejprve vyberu vsechny bojojici dvojice, davam pozor abych neparoval sebe na sebe
    from player_had_fight as p1
    inner join player_had_fight as p2 
        on (p1.fight_id eq p2.fight_id 
        and p1.player_id ne p2.player_id)
    -- K tem dvojicim klidne pripojim udaje o boji, je jedno jestli id vezmu z p1 nebo z p2
    inner join fight as f on (p1.fight_id eq p2.fight_id)
    Tak a tady je to konkretne videt: Tento dotaz mi vybere kazdy zapas 2x a to takhle:

    hracA, hracB, zapas152
    hracB, hracA, zapas152

    Protoze ted konkretne chci abych jeden hrac byl ja, tak to nevadi vyresi to pridani
    Kód:
    where player1 eq moje_id
    -- pripadne where player2 eq moje_id
    Kdybych chtel vybirat vsechny zapasici dvojice tak muzu vyuzit toho, ze id je cislo a pozmenit parovaci podminku takto:
    Kód:
    inner join player_had_fight as p2 
        on (p1.fight_id eq p2.fight_id 
        and p1.player_id LT p2.player_id)    
        -- misto nerovnosti jsem dal mensi nez, takze player 1 bude mit id vzdy mensi nez player 2 a nebudou se mi tvorit prohozene dvojice
    Po vsech upravach mam tedy tento select, jeste upravim vyber hrace podle nicku
    - vsechny moje souboje se vsemi souperi
    Kód:
    select
        p1.player_id as player1
        ,p1.nick as muj_nick
        ,p2.player_id as player2
        ,p2.nick as souperuv_nic
        ,p1.fight_id
    from player_had_fight as p1
    inner join player_had_fight as p2 
        on (p1.fight_id eq p2.fight_id 
        and p1.player_id lt p2.player_id)
    inner join fight as f on (p1.fight_id eq p2.fight_id)
    where p1.nick eq 'muj_nick'
    Ted chci ale posledni souboj, ten se urcuje podle casu pro kazdeho hrace

    Kód:
    --  dvojice player a cas posledniho zapasu. 
    select
        id_player
        ,max(time) as last_player_fight
    from player_had_fight as p
    inner join fight as f on (p.fight_id eq f.fight_id)
    group by id_player
    A pak cely tento select pouziju k ziskani prislusneho posledniho zapasu a doplnim ho do predchoziho selectu, protoze chci posledni
    zapas me a soupere, pripojuji k souperi
    Kód:
    select
        p1.player_id as player1
        ,p1.nick as muj_nick
        ,p2.player_id as player2
        ,p2.nick as souperuv_nic
        ,p1.fight_id
    from player_had_fight as p1
    inner join player_had_fight as p2 
        on (p1.fight_id eq p2.fight_id 
        and p1.player_id lt p2.player_id)
    inner join fight as f on (p1.fight_id eq p2.fight_id)
    -- vybereme pouze posledni zapasy
    inner join (
            select
                id_player 
                ,max(time) as last_player_fight
            from player_had_fight as p
            inner join fight as f on (p.fight_id eq f.fight_id)
            group by id_player
        ) as lf on (lf.id_player eq p2.id_player and f.time eq last_player_fight)
    where p1.nick eq 'muj_nick'
    V maximalnim casu nemusime hledat fight_id protoze tabulka fight by mohla mit i klic player, time ... protoze hrac nemuze mit v jednom case vice
    zapasu ... problem vyvstava, ze dva hraci maji v jednom case zapas (mezi sebou), to nam ale v tomto pripade nevadi, protoze nas zajima posledni
    zapas soupere.


    Pozn. eq (equal) pouzivam misto =, lt (lower then) misto <, le (lower equal) <=, gt (greater then) >, ge (greater equal) >= ... jen muj zvyk
    Odpovídat lze po přihlášení

Strana 1 z 3 123 PosledníPoslední

Podobná témata

  1. Reboot and select proper boot device… + PAGE_FAULT_IN_NONPAGED_AREA
    Od Czechtim v sekci Problémy s PC (HW/SW) a řešení
    Reakcí: 13
    Poslední příspěvek: 08-09-2010, 18:38
  2. mysql: insert ... select ... on duplicate key
    Od petr.svec v sekci Programování
    Reakcí: 1
    Poslední příspěvek: 09-01-2010, 12:50
  3. MySQL a JOIN
    Od petr.svec v sekci Programování
    Reakcí: 3
    Poslední příspěvek: 10-02-2009, 15:52