[SQLite] Tworzenie drzewa linków

Tworząc stronę www każdy napotka na jakieś trudności. Forumowicze na pewno pomogą!
Future_Breeze Brak danych
Expert
Expert
Avatar użytkownika
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09
Kasa: 5.00 BLM

[SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze 2010-02-06, 01:26

Witam!

Szukałem pomocy na różnych forach bezskutecznie, i przypomniałem sobie o was może wy mi pomożecie.

Otórz mam 3 tabele w bazie SQLite

Kod: Zaznacz cały
menu
id name
1 samochody
2 samochody ciężarowe
3 statki

s_menu
id menu_id name
1     1        Alfa Romeo
2     1        BMW
3     2        Star

ss_menu
id menu_id       name
1  Alfa Romeo     156
2  Alfa Romeo     166


Chciałbym z tego utworzyć takie oto drzewo

Kod: Zaznacz cały
-samochody
  - alfa romeo
    - 156
    - 166
  -bmw
-samochody ciężarowe
  -star
-statki


Z bazy danych rekordy pobieram w ten sposób

Kod: Zaznacz cały
SELECT * FROM menu AS m
LEFT JOIN s_menu AS sm ON m.id = sm.menu_id
LEFT JOIN ss_menu AS ssm ON sm.name = ssm.menu_id
ORDER BY m.name, sm.name, ssm.name ASC


I problem pojawia się z wypluwaniem drzewa, którego nie umię potrafie zrobić tylko główne kategorię. W 90% wyświetleń pokazuje się w ten sposób.

Kod: Zaznacz cały
Array
(
    [0] => Samochody
    [1] => Array
        (
            [0] => Alfa Romeo
        )

    [2] => Array
        (
            [0] => Alfa Romeo
        )

    [3] => Array
        (
            [0] => BMW
        )

    [4] => Array
        (
            [0] => Daewoo
        )

    [5] => Samochody ciężarowe
    [6] => Statki
)


usiłowałem na różne sposoby i na każdym froncie poległem, może macie jakieś ciekawe propozycje.

junior Mężczyzna
V.I.P.
V.I.P.
Avatar użytkownika
 
Posty: 717
Dołączył(a): 2008-06-22, 11:07
Kasa: 7.00 BLM
Lokalizacja: Łódź
Wyniki: 1
Imię: Tomasz
    LinuxMozilla

Postprzez junior 2010-02-06, 10:30

po pierwsze zrobiłbym to w 1 tabeli o kolumnach id id_nadrzędne nazwa
potem odpowiednio posortować i jak się zmienia wartość nadrzędnego z 0 na jakąś liczbę to tworzyć kolejny poziom zwiększając jednocześnie wskaźnik głębokości listy... gdy zmienia się nadrzędne na różną od zera zmniejszasz głębokość jeśli natrafi na nadrzędne zero zamykasz listę do nadrzędnego id.
zawsze możesz się nie zgodzić z opinią autora tego postu.

BlueMan Mężczyzna
Administrator
Administrator
Avatar użytkownika
[online]
 
Posty: 17386
Dołączył(a): 2004-05-26, 17:34
Kasa: 3.00 BLM
Bank: 140.00 BLM
Lokalizacja: Sosnowiec
Wyniki: 24
Imię: Szymon
    Windows7Chrome

Postprzez BlueMan 2010-02-06, 10:32

Ogólnie takie rzeczy robi się na jednej tabeli - z kolumną "parent", która jest NULL jak jest to rodzic, albo ma ID rodzica dla dziecka.

Nie znam dobrego sposobu, aby to wykonać w 1 zapytaniu. Robię to zawsze na 2 zapytania.

Kod: Zaznacz cały
SELECT * FROM tabela WHERE parent=NULL;

while()
{
SELECT * FROM tabela WHERE parent=4;
}


No, albo tak jak junior napisał - sortować po ID i ID_NADRZĘDNE. I w momencie wyświetlania sprawdzać czy ID_NADRZĘDNE się zmienia. Jak się zmienia to znaczy że nowe (pod)menu to ma być.
Czytaj regulamin - unikniesz wielu problemów.
Korzystajcie z załączników na forum aby pliki nie ginęły w przyszłości w zewnętrznych serwisach!

Obrazek

junior Mężczyzna
V.I.P.
V.I.P.
Avatar użytkownika
 
Posty: 717
Dołączył(a): 2008-06-22, 11:07
Kasa: 7.00 BLM
Lokalizacja: Łódź
Wyniki: 1
Imię: Tomasz
    LinuxMozilla

Postprzez junior 2010-02-06, 11:56

http://dev.mysql.com/tech-resources/art ... -data.html tu masz parę przykładów dla mysql nie ma tam większych głupot więc na lite też pójdzie

edit
w oraclu by się zastosowało CONNECT BY i po sprawie:/
zawsze możesz się nie zgodzić z opinią autora tego postu.

Future_Breeze Brak danych
Expert
Expert
Avatar użytkownika
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09
Kasa: 5.00 BLM

Re: [SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze 2010-02-06, 13:34

Ok zmontowałem jedną tabelę i w sumie to było łatwiejsze jednak dalej mam jeden problem z sortowaniem / wyświetlaniem.

Moja baza SQLite wygląda tak.

Kod: Zaznacz cały
ID NAME PARENT_ID LINK_DEPTH
1 SAMOCHODY 1 0
2 STATKI 2 0
3 ALFA ROMEO 1 2
4 156 1 4
5 166 14
5 BMW 1 2
6 E39 1 4


Pobieram to tak
Kod: Zaznacz cały
SELECT * FROM menu ORDER BY name ASC[/select]

i chciałem wyświetlić tak

[code]print '<ul>';

while($r = sqlite_fetch_array($query)) {
if($r['depth'] == 0)
  print '<li>'.$r['name'].'</li>';
   
if($r['depth'] == 2)
  print '<li>&nbsp;'.$r['name'].'</li>';

if($r['depth'] == 4)
  print '<li>&nbsp;&nbsp;'.$r['name'].'</li>';
}

print '<ul>';


Wyświetla się prawidłowo ale za nic w świecie nie chce się ułożyć w to co chciałem uzyskać w pierwszym poście. Strasznie proszę o pomoc jest mi to niezmiernie potrzebne.

junior Mężczyzna
V.I.P.
V.I.P.
Avatar użytkownika
 
Posty: 717
Dołączył(a): 2008-06-22, 11:07
Kasa: 7.00 BLM
Lokalizacja: Łódź
Wyniki: 1
Imię: Tomasz
    LinuxMozilla

Postprzez junior 2010-02-06, 17:48

teraz robisz na początku listy <ul styl> <li> na nazwa menu</li>
jeśli trafisz na element dziecko <ul><li>
gdy spada głębokość robisz </li></ul> i w czym problem
potem tylko odpowiedni styl...
<ul> zamyka całą listę...
zawsze możesz się nie zgodzić z opinią autora tego postu.

BlueMan Mężczyzna
Administrator
Administrator
Avatar użytkownika
[online]
 
Posty: 17386
Dołączył(a): 2004-05-26, 17:34
Kasa: 3.00 BLM
Bank: 140.00 BLM
Lokalizacja: Sosnowiec
Wyniki: 24
Imię: Szymon
    Windows7Chrome

Postprzez BlueMan 2010-02-06, 17:51

Future_Breeze - 2010-02-06, 12:34 napisał(a):Wyświetla się prawidłowo ale za nic w świecie nie chce się ułożyć

nie rozumiem za bardzo :)

junior - 2010-02-06, 10:56 napisał(a):w oraclu by się zastosowało CONNECT BY i po sprawie:/

Masz gdzieś na wierzchu przykład do tego? :)



== EDIT
Po tym co junior napisał to wiem o co chodzi ;]
Kod: Zaznacz cały
while($r = sqlite_fetch_array($query)) {
if($r['depth'] == 0)
  print '<li>'.$r['name'].'</li>';
   
if($r['depth'] == 2)
  print '<li style="padding-left: 40px">&nbsp;'.$r['name'].'</li>';

if($r['depth'] == 4)
  print '<li style="padding-left: 60px">&nbsp;&nbsp;'.$r['name'].'</li>';
}
Czytaj regulamin - unikniesz wielu problemów.
Korzystajcie z załączników na forum aby pliki nie ginęły w przyszłości w zewnętrznych serwisach!

Obrazek

Future_Breeze Brak danych
Expert
Expert
Avatar użytkownika
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09
Kasa: 5.00 BLM

[SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze 2010-02-06, 22:21

Panowie nie potrafię wyświetlić tego za pomocą PHP, próbowałem z tablicami wielowymiarowymi, próbowałem też wyświetlić to na różne inne sposoby niestety mój mózg nie umie pojąć jak to wyświetlić.

Tak to mniej więcej zawsze mi wygląda i jest dalekie od ideału :P
blad.jpg


Jest mi to niesamowicie potrzebne, mógłbym wam nawet za to zapłacić :)
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.

junior Mężczyzna
V.I.P.
V.I.P.
Avatar użytkownika
 
Posty: 717
Dołączył(a): 2008-06-22, 11:07
Kasa: 7.00 BLM
Lokalizacja: Łódź
Wyniki: 1
Imię: Tomasz
    LinuxMozilla

Postprzez junior 2010-02-07, 11:30

no ale zaraz zaraz jeżeli wyświetla ci tak jak na obrazku to jest to dokładnie to co napisałeś w kodzie... &nbsp; to nie łamalna spacja jeśli chcesz myślniki to je dopisz... po prostu nie mogę dojść do tego co chcesz zrobić...
i jeszcze przykładowy kod co prawda od troszkę innego zagadnienia bo wyciągnięty z virtuemarta a raczej dopisany do niego by było menu w formie listy, ze zwiniętymi poziomami więc parę rzeczy trzeba by wywalić ale pokazuje ci to zasadę
Kod: Zaznacz cały
   
            /* New code to create $html... as unordered list */
            if( $n == 0 ) {
                // First item
                $html .= '<ul class="menu">';
            } else if ( $depth_list[$n] > $poziom ) {
                // New subcategory
                $html .= '<ul>';
            } else if ( $depth_list[$n] < $poziom) {
                // End of subcategory
                $html .= '</li>';
                $html .= str_repeat( '</ul></li>', $poziom - $depth_list[$n] );
            } else {
                // All other possibilities. Need to finish off <li> command.
                $html .= '</li>';
            }

            $html .= '
            <li '.$append.''.$css_class.'><a title="'.$catname.'" href="'. $sess->url(URL."index.php?page=shop.browse&amp;category_id=".$category_tmp[$row_list[$n]]["category_child_id"]) .'"><span>'
            . $catname
            . ps_product_category::products_in_category( $category_tmp[$row_list[$n]]["category_child_id"] )
            .'</span></a>';

            $poziom = $depth_list[$n];
        }


co do pytania bluemana:
http://www.psoug.org/reference/connectby.html
Ostatnio edytowano 2010-02-07, 11:38 przez junior, łącznie edytowano 2 razy
zawsze możesz się nie zgodzić z opinią autora tego postu.

BlueMan Mężczyzna
Administrator
Administrator
Avatar użytkownika
[online]
 
Posty: 17386
Dołączył(a): 2004-05-26, 17:34
Kasa: 3.00 BLM
Bank: 140.00 BLM
Lokalizacja: Sosnowiec
Wyniki: 24
Imię: Szymon
    Windows7Firefox

Postprzez BlueMan 2010-02-07, 11:35

Future_Breeze podaj jak wygląda teraz Twoje zapytanie.
Czytaj regulamin - unikniesz wielu problemów.
Korzystajcie z załączników na forum aby pliki nie ginęły w przyszłości w zewnętrznych serwisach!

Obrazek

Future_Breeze Brak danych
Expert
Expert
Avatar użytkownika
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09
Kasa: 5.00 BLM

Re: [SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze 2010-02-07, 11:57

Baza danych wygląda dokładnie tak

Kod: Zaznacz cały
if($db = sqlite_open('test_db.sqlite', 0666, $e)) {

sqlite_query($s, "CREATE TABLE menu(id INTEGER PRIMARY KEY NOT NULL,
                           link_text VARCHAR NOT NULL,
                           link_depth INTEGER NOT NULL,
                           parent_id INTEGER NOT NULL)");


sqlite_query($s, "INSERT INTO menu VALUES(NULL, 'Samochody', '0', '1')");
sqlite_query($s, "INSERT INTO menu VALUES(NULL, 'Statki', '0', '2')");

sqlite_query($s, "INSERT INTO menu VALUES(NULL, 'Alfa Romeo', '2', '1')");
sqlite_query($s, "INSERT INTO menu VALUES(NULL, 'BMW', '2', '1')");

sqlite_query($s, "INSERT INTO menu VALUES(NULL, '156', '4', '1')");
sqlite_query($s, "INSERT INTO menu VALUES(NULL, 'e39', '4', '1')");
sqlite_query($s, "INSERT INTO menu VALUES(NULL, '166', '4', '1')");

} else {
exit($e);
}



Pobieram dane tak

Kod: Zaznacz cały
SELECT * FROM menu



A najnowszy sposób wyświetlenia chciałem zrobić tak niestety nie mam pomysłu na inkrementacje zmiennej $m. I nie wiem czy to ma wogóle jakiś sens bytu.

Kod: Zaznacz cały
if($db = sqlite_open('test_db.sqlite', 0666, $e)) {

$query = sqlite_query($db, "SELECT * FROM menu");

} else {
exit($e);
}

$c = sqlite_num_rows($query);
$m = 1;

for($i = 0; $i < $c; $i++) {

$r = sqlite_fetch_array($sql_query);

     if($r['link_depth'] == 0 && $r['parent_id'] == $m) {
      print $r['link_text'].'<br/>';
     }
     if($r['link_depth'] == 2 && $r['parent_id'] == $m) {
      print '&nbsp;&nbsp;&nbsp;&nbsp;'.$r['link_text'].'<br/>';
     }
     if($r['link_depth'] == 4 && $r['parent_id'] == $m) {
      print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$r['link_text'].'<br/>';
     }
}



Z góry niesamowicie dziękuje za udzieloną mi pomoc.

junior Mężczyzna
V.I.P.
V.I.P.
Avatar użytkownika
 
Posty: 717
Dołączył(a): 2008-06-22, 11:07
Kasa: 7.00 BLM
Lokalizacja: Łódź
Wyniki: 1
Imię: Tomasz
    LinuxMozilla

Postprzez junior 2010-02-07, 12:00

przeanalizowałeś to co wkleiłem?

-edit
no cóż dostaniesz gotowca:
http://wklej.to/rfCX
wynik
http://wklej.to/79Jf
Ostatnio edytowano 2010-02-07, 14:27 przez junior, łącznie edytowano 2 razy
zawsze możesz się nie zgodzić z opinią autora tego postu.

Future_Breeze Brak danych
Expert
Expert
Avatar użytkownika
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09
Kasa: 5.00 BLM

Re: [SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze 2010-02-07, 13:17

Nie przeanalizowałem, ponieważ nie wiem jak to się stało ale przeoczyłem Twój post.
Zaraz zobaczę.
Przepraszam za kłopot.

no ale zaraz zaraz jeżeli wyświetla ci tak jak na obrazku to jest to dokładnie to co napisałeś w kodzie... &nbsp; to nie łamalna spacja jeśli chcesz myślniki to je dopisz...


Chciałbym poprostu uzyskać to co na obrazku jest widoczne tylko, że posortowane i to jest dla mnie największy problem.

Miałoby to wyglądać tak

Kod: Zaznacz cały
Samochody
  Alfa Romeo
    156
    166
  BMW
    e39
Statki


A wygląda to tak jak na załączonym obrazku.

Kod: Zaznacz cały
Samochody
Statki
  Alfa Romeo
  BMW
    156
    e39
    166

junior Mężczyzna
V.I.P.
V.I.P.
Avatar użytkownika
 
Posty: 717
Dołączył(a): 2008-06-22, 11:07
Kasa: 7.00 BLM
Lokalizacja: Łódź
Wyniki: 1
Imię: Tomasz
    LinuxMozilla

Postprzez junior 2010-02-07, 14:10

to znaczy że kategoria nadrzędna tego modelu bwm jest źle ustawiona
http://wklej.to/rfCX
drobna pomyłka w kodzie...
Kod: Zaznacz cały
    * Samochody
          o Alfa Romeo
                + 156
                + 166
          o BMW
                + e39
    * Statki

choć nie testowałem tego dokładnie
zawsze możesz się nie zgodzić z opinią autora tego postu.

Future_Breeze Brak danych
Expert
Expert
Avatar użytkownika
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09
Kasa: 5.00 BLM

Postprzez Future_Breeze 2010-02-07, 14:42

Ten kod, który mi wysłałeś wygląda solidnie wieczorem go przetestuje.
Wielkie dzięki.

junior Mężczyzna
V.I.P.
V.I.P.
Avatar użytkownika
 
Posty: 717
Dołączył(a): 2008-06-22, 11:07
Kasa: 7.00 BLM
Lokalizacja: Łódź
Wyniki: 1
Imię: Tomasz
    LinuxMozilla

Postprzez junior 2010-02-07, 14:49

tylko popraw strukturę bazy, by te modele miały takie id nadrzędne jak id ich marki... bo się będzie pitolić:D
ten kod nie jest solidny, jest pisany mocno na szybko... jest po prostu zrobiona wielowymiarowa tablica a potem wypisana, tak naprawdę powinno być to rekursją robione by można było więcej poziomów zagłębienia itp. ale tak chyba będzie łatwiej zrozumieć o co mi chodziło:)
zawsze możesz się nie zgodzić z opinią autora tego postu.

Future_Breeze Brak danych
Expert
Expert
Avatar użytkownika
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09
Kasa: 5.00 BLM

Postprzez Future_Breeze 2010-02-08, 21:58

Kod działa bardzo poprawnie dziękuje wam uprzejmie za pomoc :)


  • Inne strony

Powrót do Webmasterka

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 gości

Strona główna forum