[mysql] Drzewko kategorii i takie tam....
plumpcio - 29-03-2006 00:26
[mysql] Drzewko kategorii i takie tam....
Mam mniej wiecej takie dane w bazie mysql:
ID RODZIC NAZWA 1 0 glowna 1 2 1 kategoria 1 3 1 kategoria 2 4 3 podkategoria 1 5 0 glowna 2
wiem już jak narysować drzewko
glowna 1 ---Kateogria 1 ---kategoria 2 ------podkategoria 1 glowna 2
teraz po kliknięciu w "glowna 1" chcialbym otrzymać ID wszystkich podkategorii znajdujacych sie w "glowna 1" - czyli 2, 3, ale także 4 (podkategoria 1). inny przypadek - po kliknięciu w "kategoria 2" powinienem dostać ID "podkategoria 1" i nic więcej. czy da się to załatwić na poziomie samej bazy danych (mysql) ? a jeśli tak to jak ? bo nie mam już na to pomysłu, będe wdzięczny za małą podpowiedź
-- pozdr.
Wojtek pBT (prac) - 29-03-2006 00:26
plumpcio napisał(a): > Mam mniej wiecej takie dane w bazie mysql: > > ID RODZIC NAZWA > 1 0 glowna 1 > 2 1 kategoria 1 > 3 1 kategoria 2 > 4 3 podkategoria 1 > 5 0 glowna 2 > > > wiem już jak narysować drzewko > > glowna 1 > ---Kateogria 1 > ---kategoria 2 > ------podkategoria 1 > glowna 2 > > > teraz po kliknięciu w "glowna 1" chcialbym otrzymać ID wszystkich > podkategorii znajdujacych sie w "glowna 1" - czyli 2, 3, ale także 4 > (podkategoria 1). inny przypadek - po kliknięciu w "kategoria 2"
przy tej strukturze tabel bez procedury składowanej nie dasz rady. Ale czemu ty nie RTFM? -> http://www.dbf.pl/faq/tresc.html?rozdzial=1#o1_9
pBT
keczerad - 29-03-2006 00:27
Wojtek pBT (prac) napisał(a):
> > przy tej strukturze tabel bez procedury składowanej nie dasz rady. > Ale czemu ty nie RTFM? -> http://www.dbf.pl/faq/tresc.html?rozdzial=1#o1_9
moim zdaniem wystarcza same selecty bo to trzeba zrobi na warstwie programowej bo jakos nie widze zastosowania drzewka w samym SQL, trzeba to raczej przedstawic userowi.
Patrz tu :
http://www.e-mo.com.pl/kategoria,305,0,komponenty.html
--
keczerad
http://www.e-mo.com.pl sklep w (X)HTML
Artur - 30-03-2006 01:26
Jako ciekawostkę. W niektórych bazach, np. w DB2 Express-C (darmowa baza) można takie drzewo wyświetlić pojedynczym (rekurencyjnym) zapytaniem SQL, bez konieczności robienia wielu SQL-i w procedurze.
Oto przykład takiego zapytania rekurencyjnego:
WITH wynik(rodzic, dziecko, nazwa) AS ( SELECT rodzic, dziecko, nazwa FROM drzewo WHERE rodzic = 1 UNION ALL SELECT d.rodzic, d.dziecko, d.nazwa FROM drzewo d, wynik w WHERE w.dziecko = d.rodzic ) SELECT rodzic, dziecko, nazwa FROM wynik ;
Pewnie na początek trochę trudno zrozumieć o co chodzi, ale działa i praktycznie nie ma ograniczenia co do poziomu zagłębień. Zapytanie jest dużo wydajniejsze niż wysyłanie n-zapytań do bazy, ponieważ optymalizowane jest tylko raz (oczywiście powinny być indeksy na polach rodzic, dziecko).
Definicja tabeli:
create table drzewo( rodzic int, dziecko int, nazwa char(25));
Do wyniku zapytania można dodać dynamicznie nowe kolumny, np: wyliczany poziom zagłębienia oraz ścieżkę od elementu wyszukiwanego do danego węzła w drzewie:
WITH wynik(rodzic, dziecko, nazwa, poziom, kolejnosc) AS ( SELECT rodzic, dziecko, nazwa, 0, sklej(cast(rodzic as char(30)),dziecko) FROM drzewo WHERE rodzic = 1 UNION ALL SELECT d.rodzic, d.dziecko, d.nazwa, w.poziom+1, sklej(w.kolejnosc, d.dziecko) FROM drzewo d, wynik w WHERE w.dziecko = d.rodzic ) SELECT rodzic, dziecko, nazwa, poziom, kolejnosc FROM wynik order by kolejnosc ;
Gdzie sklej jest odpowiednio napisaną funkcją sklejającą rodzica (int) i dziecko (int), tak by powstała ścieżka. Oto przykładowy rezultat zapytania przy prostym konkatenowaniu (oczywiście trzeba przerobić funkcję sklej, tak by np. każdy węzeł był prezentowany w postaci dłuższego ciągu znaków):
RODZIC DZIECKO NAZWA POZIOM KOLEJNOSC
1 2 Glo 1/Kat 1 0 1/2
2 11 Glo 1/kat 1/Pod 2 1 1/2/11
2 7 Glo 1/kat 1/Pod 1 1 1/2/7
7 10 Glo 1/kat 1/Pod 1/1 2 1/2/7/10
1 3 Glo 1/Kat 2 0 1/3
3 4 Glo 1/kat 2/Pod 1 1 1/3/4
Dane wejściowe, RODZIC, DZIECKO, NAZWA:
0,1,"Glo 1 " 0,5,"Glo 2 " 1,2,"Glo 1/Kat 1 " 1,3,"Glo 1/Kat 2 " 5,8,"Glo 2/Kat 1 " 2,7,"Glo 1/kat 1/Pod 1 " 2,11,"Glo 1/kat 1/Pod 2 " 3,4,"Glo 1/kat 2/Pod 1 " 8,9,"Glo 2/Kat 1/Pod 1 " 7,10,"Glo 1/kat 1/Pod 1/1"
Pozdrawiam,
-- Artur Wronski
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[mysql] =?ISO-8859-2?Q?Za=E6mienie=2E=2E=2E_jak_wy=B6wietli=E6?==?ISO-8859-2?Q?=2E=2E=2E?=
[mysql] =?ISO-8859-2?Q?wielko=B6=E6_bazy_a_stabilno=B6=E6=2C?==?ISO-8859-2?Q?_podzia=B3_du=BFej_bazy_a_powi=B1zania_tabel?=
[MySQL] =?ISO-8859-2?Q?Wy=B6wietlenie_kolejnej_pozycji=2C_?==?ISO-8859-2?Q?jak=B1_mia=B3by_dany_rekord=2C_gdybym_czyta=B3 _?==?ISO-8859-2?Q?wg_konkretnych_kryteri=F3w=2E_Da_si=EA_=3F?=
[mysql 4.0.x] przenoszenie kolum =?ISO-8859-2?Q?mi=EAdzy_bazam?==?ISO-8859-2?Q?i_cd_=2E=2E=2E_?=
[MySQL] =?ISO-8859-2?Q?z=B3=B1czenie_tabeli_u=BFytkownik_i?==?ISO-8859-2?Q?_zdj=EAcia_z_wyborem_zdj=EAcia_domy=B6lnego?=
[MySQL] Jak =?ISO-8859-2?Q?wpisa=E6_do_tabeli_pozycje_dl?==?ISO-8859-2?Q?a_wierszy_gdybym_te_wiersze_wybiera=B3_w_ok?== ?ISO-8859-2?Q?re=B6lonej_kolejno=B6ci_=3F?=
Gdzie MySQL 4.1, a gdzie 5.0?
[MySQL 4.0...4.1] zabezpieczenie przed =?ISO-8859-2?Q?jednoczesn?==?ISO-8859-2?Q?=B1_edycj=B1?=
[MS SQL] "set names" (mySQL) w MS SQL
[mysql 5.x] jak =?ISO-8859-2?Q?zrealizowa=E6_zapytanie=3F_cz?==?ISO-8859-2?Q?yli_podzapytanie_i_wi=EAcej_ni=BF_jeden_rz=B1? ==?ISO-8859-2?Q?d_wynik=F3w?=
zanotowane.pldoc.pisz.plpdf.pisz.plczterowers.keep.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|