[SQLite] Tworzenie drzewa linków

Tworząc stronę www każdy napotka na jakieś trudności. Forumowicze na pewno pomogą!

[SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze » 2010-02-06, 01:26:06

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.
Avatar użytkownika
Future_BreezeNone specified
Expert
Expert
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09:10
Podziękował : 0 razy
Otrzymał podziękowań: 0 razy

Postprzez junior » 2010-02-06, 10:30:49

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.
Avatar użytkownika
juniorMale
V.I.P.
V.I.P.
 
Posty: 1446
Dołączył(a): 2008-06-22, 11:07:52
Lokalizacja: Łódź
Podziękował : 0 razy
Otrzymał podziękowań: 4 razy

Postprzez BlueMan » 2010-02-06, 10:32:26

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.
Avatar użytkownika
BlueManMale
Administrator
Administrator
 
Posty: 19105
Dołączył(a): 2004-05-26, 17:34:59
Lokalizacja: Dabrowa Górn.
Podziękował : 6 razy
Otrzymał podziękowań: 5 razy
Imię: Szymon

Postprzez junior » 2010-02-06, 11:56:44

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.
Avatar użytkownika
juniorMale
V.I.P.
V.I.P.
 
Posty: 1446
Dołączył(a): 2008-06-22, 11:07:52
Lokalizacja: Łódź
Podziękował : 0 razy
Otrzymał podziękowań: 4 razy

Re: [SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze » 2010-02-06, 13:34:29

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.
Avatar użytkownika
Future_BreezeNone specified
Expert
Expert
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09:10
Podziękował : 0 razy
Otrzymał podziękowań: 0 razy

Postprzez junior » 2010-02-06, 17:48:09

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.
Avatar użytkownika
juniorMale
V.I.P.
V.I.P.
 
Posty: 1446
Dołączył(a): 2008-06-22, 11:07:52
Lokalizacja: Łódź
Podziękował : 0 razy
Otrzymał podziękowań: 4 razy

Postprzez BlueMan » 2010-02-06, 17:51:17

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.
Avatar użytkownika
BlueManMale
Administrator
Administrator
 
Posty: 19105
Dołączył(a): 2004-05-26, 17:34:59
Lokalizacja: Dabrowa Górn.
Podziękował : 6 razy
Otrzymał podziękowań: 5 razy
Imię: Szymon

[SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze » 2010-02-06, 22:21:19

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
blad.jpg (37.88 KiB) Przeglądane 3932 razy


Jest mi to niesamowicie potrzebne, mógłbym wam nawet za to zapłacić :)
Avatar użytkownika
Future_BreezeNone specified
Expert
Expert
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09:10
Podziękował : 0 razy
Otrzymał podziękowań: 0 razy

Postprzez junior » 2010-02-07, 11:30:50

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:48 przez junior, łącznie edytowano 2 razy
zawsze możesz się nie zgodzić z opinią autora tego postu.
Avatar użytkownika
juniorMale
V.I.P.
V.I.P.
 
Posty: 1446
Dołączył(a): 2008-06-22, 11:07:52
Lokalizacja: Łódź
Podziękował : 0 razy
Otrzymał podziękowań: 4 razy

Postprzez BlueMan » 2010-02-07, 11:35:17

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.
Avatar użytkownika
BlueManMale
Administrator
Administrator
 
Posty: 19105
Dołączył(a): 2004-05-26, 17:34:59
Lokalizacja: Dabrowa Górn.
Podziękował : 6 razy
Otrzymał podziękowań: 5 razy
Imię: Szymon

Re: [SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze » 2010-02-07, 11:57:58

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.
Avatar użytkownika
Future_BreezeNone specified
Expert
Expert
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09:10
Podziękował : 0 razy
Otrzymał podziękowań: 0 razy

Postprzez junior » 2010-02-07, 12:00:16

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:23 przez junior, łącznie edytowano 2 razy
zawsze możesz się nie zgodzić z opinią autora tego postu.
Avatar użytkownika
juniorMale
V.I.P.
V.I.P.
 
Posty: 1446
Dołączył(a): 2008-06-22, 11:07:52
Lokalizacja: Łódź
Podziękował : 0 razy
Otrzymał podziękowań: 4 razy

Re: [SQLite] Tworzenie drzewa linków

Postprzez Future_Breeze » 2010-02-07, 13:17:54

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
Avatar użytkownika
Future_BreezeNone specified
Expert
Expert
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09:10
Podziękował : 0 razy
Otrzymał podziękowań: 0 razy

Postprzez junior » 2010-02-07, 14:10:27

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.
Avatar użytkownika
juniorMale
V.I.P.
V.I.P.
 
Posty: 1446
Dołączył(a): 2008-06-22, 11:07:52
Lokalizacja: Łódź
Podziękował : 0 razy
Otrzymał podziękowań: 4 razy

Postprzez Future_Breeze » 2010-02-07, 14:42:39

Ten kod, który mi wysłałeś wygląda solidnie wieczorem go przetestuje.
Wielkie dzięki.
Avatar użytkownika
Future_BreezeNone specified
Expert
Expert
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09:10
Podziękował : 0 razy
Otrzymał podziękowań: 0 razy

Postprzez junior » 2010-02-07, 14:49:28

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.
Avatar użytkownika
juniorMale
V.I.P.
V.I.P.
 
Posty: 1446
Dołączył(a): 2008-06-22, 11:07:52
Lokalizacja: Łódź
Podziękował : 0 razy
Otrzymał podziękowań: 4 razy

Postprzez Future_Breeze » 2010-02-08, 21:58:28

Kod działa bardzo poprawnie dziękuje wam uprzejmie za pomoc :)
Avatar użytkownika
Future_BreezeNone specified
Expert
Expert
 
Posty: 1178
Dołączył(a): 2004-09-05, 15:09:10
Podziękował : 0 razy
Otrzymał podziękowań: 0 razy


  • Inne

Powrót do Webmasterka

Kto przegląda forum

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

cron