Autor Zpráva
thingwath
Profil
Mám dvě tabulky, články a kategorie. Ty zajímavé sloupce z nich vypadají takto:

článek má sloupec id_kategorie, což je odkaz na kategorii pod kterou přímo spadá

kategorie má svoje id a sloupec id_nad, který odkazuje na nadřazenou kategorii a vytváří tak ten strom.

Problém teď nastává v tom, že potřebuji vybrat všechny články, které spadají pod nějakou kategorii (potud žádný problém), ale i pod její podkategorie. A s tím si už tak jednoduše rady nevím. Díky za rady.

(doplňuji, že hloubka možných podkategorií není pevná, může to být nula nebo taky klidně padesát)
souki
Profil
úplně jsem nepochopil kterým směrem je to potřeba, ale já na to měl někde rekurzi v php... jako parametr se jí dalo id kategorie a ona se volala a ukládala do pole všechny id, které potkala v podkategorii. Jen si dát pozor na přepisování hlavní proměnné a je to...
Jak to udělat an straně databáze by mě ale také zajímalo
thingwath
Profil
Je potřeba vybrat články, které mají id_kategorie x a hlavně všechny články, které mají id_kategorie nějaké y, kde y je kategorie která má _někde_ (ne nutně bezprostředně) nad sebou (v id_nad) kategorii x. Procházet to v PHP mi není moc milé.
Joker
Profil
Tak tohle bude "legrace". Ten zásadní problém tedy je jak SQL dotazem vybrat všechny nadřazené prvky stromu.
Mně zatím napadá jedině pozměnit návrh tabulky tak, aby ukládala i nepřímé vazby... čímž se ale zesložití údržba
thingwath
Profil
Já vím, že je to problém. Jinak bych se neptal :-) Trochu změnit tabulky mě napadlo, ale to není zrovna co bych chtěl. Tohle kejklování potřebuju jenom víceméně pro jedinou věc (všude jinde se to už nějak obešlo nebo to tam prostě není potřeba), takže bych kvůli tomu nerad měnil nějak radikálně moc věcí.
H13
Profil
A co tak nějak projet rekurzivní funkci celý strom kategorie:

Uroven 0 (kategorie a) - Uroven 1 (kategorie x) - Uroven 2 (kategorie b) - clanek --> kategorie x = true
Uroven 0 (kategorie a) - Uroven 1 (kategorie c) - Uroven 2 (kategorie x) - clanek --> kategorie x = true
Uroven 0 (kategorie a) - Uroven 1 (kategorie d) - Uroven 2 (kategorie e) - clanek --> kategorie x = false
Uroven 0 (kategorie a) - Uroven 1 (kategorie x) - clanek --> kategorie x = true

výpis stromu provést nějak takto i s podmínkama:

function zobraz_strom($nadKategorieID) {
$result = mysql_query("SELECT * FROM kategorie WHERE nadKategorieID=$nadKategorieID");
while ($row = mysql_fetch_assoc($result)) {
----
a sem vložit nějakou podmínku aby to zachycovalo kategorii x a rozdělovalo jednotlivá vlánka stromu ???
$row['kategorieID']
----
zobraz_strom($row['kategorieID']);
}
}
thingwath
Profil
H13
To mě samozřejmě napadlo, ale ideální by bylo udělat to na databázi celé, protože už teď je těch dotazů víc než by bylo zdrávo. Tohle co popisuješ by mohlo udělat nějakých dvěstě dotazů klidně. To je dost neefektivní.
H13
Profil
To mě samozřejmě napadlo, ale ideální by bylo udělat to na databázi celé, protože už teď je těch dotazů víc než by bylo zdrávo. Tohle co popisuješ by mohlo udělat nějakých dvěstě dotazů klidně. To je dost neefektivní.

souhlas... taky by mě zajímalo jak to vyřešit pomocí databáze
Kajman_
Profil *
V db to není problém.... alespoň na oracle ;-)
thingwath
Profil
Já to zapoměl říct. MySQL 5... já si to nevymyslel. (stačí tip, já už to nějak dohromady dam)
Kajman_
Profil *
možná by se to dalo udělat takle nějak...

select group_concat(id_kategorie order by id_kategorie) tmpkat from tabulka where id_kategorie in ($tmpkat) or id_nad in ($tmpkat)

a volat to do té doby, dokud ten pomocný seznam $tmpkat nebude stejný jako naposledy volaný.
monarcha
Profil
já tohle řeším tak, že mimo ID si ukládám do databáze všechny předešlé ID (třeba do sloupce strom) například takto:
root - podkategorie1 - podkategorie2
root bude mít strom=1.
podkategorie1 bude mít strom=1.2.
podkategorie2 bude mít strom=1.2.3.
atd.
Pro jednoduchej výpis to stačí seřadit podle sloupce strom, počet teček určuje stupeň zanoření. Když je potřeba to řadit trochu složitěji, nedělám přes SQL ale v php funkcí array_multisort ..
Toto téma je uzamčeno. Odpověď nelze zaslat.

0