Vlákno názorů k článku PHP okénko: Spojování tabulek od gemda - hello, aj ja mam pocit ze sa viac...

  • Článek je starý, nové názory již nelze přidávat.
  • 11. 4. 2005 20:46

    gemda (neregistrovaný)
    hello, aj ja mam pocit ze sa viac pise o mysql ako o php, a system zobrazovania ukazkoveho kodu je dost krkolomny, ale cert to ber.

    Nahodou mam otazku (ak mozem) pretoze som nedavno riesil zobrazovanie poloziek po skupinach len trochu v inom pripade a nakoniec som nevyuzil ziadnu podobnu moznost ako je tu v clanku resp. v odpovediach, hoci som vyskusal naozaj kopu moznosti.

    Moja situacia:
    Vytvaral som tabulku pre obycajne web-forum. Chcel som aby sa jeho zlozky dali rozlozit do 4roch skupin. Kategoria, Sekcia, Forum a nakoniec samotne Prispevky vo forach. Jednoducho aby ked navstevnik dorazi na moje forum najprv uvidel Sekcie For zgrupene v Kategoriach. Potom ako klikne na nejaku sekciu zobrazi sa mu zoznam For z tejto sekcie a ked klikne na forum tak uvidi jeho Prispevky. Dufam ze sa to da pochopit :)

    Druhou mojou poziadavkou bolo aby sa to dalo vsetko natlacit do jednej tabulky. Jedine ak by som chcel robit nieco ako permissions... tak na to by som potreboval dalsiu tabulku, ale o to nejde.

    takze som navrhol takuto tabulku "forum" (pouzivam MySQL 4.0???)

    -------
    id INT PRIMARY KEY AUTO_INCREMENT *** ako identifikacne cislo polozky

    level TINYINT *** tento parameter by niesol informaciu o tom ci je polozka kategoriou(level=0) sekciou(level=1) forom(level=2) alebo prispevkom(level=3)

    owner INT *** uchova informaciu rodicovskej polozky, cize pre Sekcie to bude NULL lebo su najvyssimi moznymi jednotkami v hierarchii ale pre ostatne 3 typy spomenutych poloziek to bude prislusna referencia na "id" parameter v tejto tabulke.

    title TEXT, content TEXT, time DATETIME *** uz spominam len pre pripad ze by som ich niekde potreboval spomenut, podstatne su len prve tri parametre (id,level a owner)
    ------


    takze ked uzivatel dorazi do mojho fora chcel som aby ako prve uvidel nieco take jednoduche ako:

    Kategoria 1
    -- Sekcia 1
    -- Sekcia 2
    -- Sekcia 3

    Kategoria 2
    -- Sekcia 1
    -- Sekcia 2

    Kategoria 3
    -- Sekcia 1
    -- Sekcia 2
    -- Sekcia 3
    -- Sekcia 4

    atd.

    Najprv som si myslel ze moj problem vyriesi obycajny SELECT s pouzitim GROUP BY. Nieco ako:
    SELECT * FROM forum WHERE level=0 OR level=1 GROUP BY level,owner.
    v skutocnosti som vyskusal mnoho kombinacii takehoto podobneho zapisu (myslim zmenou columnov v podmienkach), ale nic z toho nefungovalo tak ako som si to prial, ziadne grupenie sa nekonalo, vlastne ked sa nad tym zamyslim tak ani neviem podla coho by mala databaza vediet ze podla coho mala jednotky grupovat. Co viedlo k tomu ze vlastne ani neviem na co parameter GROUP BY sluzi a co v konecnom dosledku akurat svedci o tom ze som neschopny sa ucit vyznamu funkcii :))) nevadi.

    chcel som zistit ci sa daju na tento ucel pouzit aj JOIN funkcie ale tam sa opat potvrdila moja neschopnost rozumiet funkciam, asi je to na moj mozog too much :)

    zufalo som sa pokusal zakomponovat aj flow control podmienky ako IF, ktore po niekolko hodinovom badani tiez neviem ako a naco pouzit :)) vobec v nejakom pripade... smutne

    zamyslal som sa aj nad zverenim tejto grupovacej ulohy na bremena php ale to by si zrejme vyzadovalo plnenie nejakeho pola kopou dat a potom ich zoradovat hhmmmm, tak som to viacmenej natrvalo zamietol

    a asi za 24 hodin tazkeho badania, som po stovkach upravach pociatocneho selektu, zakomponovani funkcie UNION a obycajneho aliasingu nasiel sposob ako moje Kategorie a Sekcie zobrazit pekne vygrupene a to iba v jednom query s tym ze php ich uz dostane pekne vygrupene:

    (SELECT *,id AS arrange WHERE level=0 ORDER BY title ASC) UNION (SELECT *,owner AS arrange WHERE level=1 ORDER BY title ASC) ORDER BY arrange;

    Cize vysledkom je jedna tabulka kde sa vykonaju dva selekty z tej istej tabulky, pricom v prvom selekte sa vyberu vsetky kategorie tentokrat zoradene abecedne podla nazvu(title) a v druhom selekte sa vyberu vsetky sekcie tiez zoradene podla nazvu, pricom sa (zrejme) oba selekty vykonaju nasledne ale do tej istej vyslednej tabulky. Nakoniec sa ale zoradia podla novovzniknuteho stlpca arrange ktory vlastne vedie iba cisla ownerov bez ohladu na to ci je to polozka nadradenej kategorie alebo podradenej sekcie. Mozno vas teraz napadla otazka preco by vlastne malo byt vsetko zoradene tak ako si to prajem ked sa tabulka zoraduje podla arrange, co ak sa kategoria strati medzi svojimi detmi vo vyslednom liste? nestrati sa, bude vzdy prva, pretoze prvy selekt vyberal prave kategorie a druhy prave sekcie, preto budu kategorie vzdy "akoby nadradene" sekciam, a teda sa zobrazia najprv, a potom ich sekcie.

    Samozrejme ze nechcem vzdy aby boli Kategorie radene podla nazvu alfabeticky vzostupne tak som este neskor dotvoril stlpec "ordernum INT" podla ktoreho potom riesim ORDER BY podla prednastavenych cisel.

    A teraz moja otazka:
    Aj napriek tomu ze toto riesenie prevedie iba dva selekty a plne splni moju poziadavku, nezda sa mi to uplne orechove. Moje znalosti o databazach su velmi biedne ako vidite, a tak prosim ak mozte a hlavne VIETE, tak prosim poradte ako zriesit taky isty vystup pouzitim spajania tabuliek (neviem ktore JOIN by to malo byt) s uvedenim presneho query podla parametrov ake som tu nacrtol. Alebo aspon spomente co je nie dobre na tom mojom selecte.

    Ale ak nieste poradna tak sa ospravedlnujem za zbytocne otravovanie.

    Dakujem
  • 12. 4. 2005 8:40

    anonymní
    No, ja tiez nie som expert ako vsetci ostatni diskutujuci, ale riesil by som to asi takto:

    select kat.id, kat.nazov, sek.id, sek.nazov
    from test as kat
    left join test as sek on sek.owner=kat.id
    where kat.level=0

    Left join koli tomu, aby sa vypisali aj kategorie, ktore nemaju sekcie...
    Samozrejme este treba spravit index nad owner (a level).
  • 12. 4. 2005 11:59

    Jakub Vrána
    V první řadě vaší pozornosti doporučuji článek http://www.root.cz/clanky/stromy/ nebo http://interval.cz/clanek.asp?article=3801. Asi by bylo lepší přizpůsobit strukturu databáze.