Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zapytanie SQL
Forum PHP.pl > Forum > Bazy danych > MySQL
Prezi2907
Witam.

Mam takie pytanko, jest sobie taka tabelka:

  1. ID GRUPA OBECNA GRUPA_GLOWNA NAZWA
  2. 1 | 1 | 1 | Grupa Główna
  3. 2 | 2 | 1 | Podgrupa grupy głównej
  4. 3 | 3 | 2 | Podgrupa 2 poziomu
  5. 4 | 4 | 2 | Podgrupa 2 poziomu
  6. 5 | 5 | 3 | Podgrupa 3 poziomu
  7. 6 | 6 | 4 | Podgrupa 4 poziomu


Teraz chodzi o zapytanie , najlepiej jedno, które będzie wyciągało nam grupę główną później podgrupę , wszystkie podgrupy grupy głównej z tych wszystkich podgrup po kolei wszystkie ich podgrupy 2 poziomu a następnie z nich kolejne wszystkie podgrupy 3 poziomu i tak dalej...

Wstępnie myślałem nad użyciem uniona ale to się nie sprawdza.
miałem też takie zapytanie które działa dobrze póki się nie zmienią grupy obecne pozycji
  1. SELECT nazwa , ID FROM tabela ORDER BY (case when grupa=grupa_glowna then grupa_glowna else grupa id) , nazwa ;


Później orbi się już coraz większy bałagan. W PHP rozwiązałem problem poprzez osobne 3 zapytania ale to zero optymalizacji jest (zapytanie generuje się fakt w niecałe 0.02 s. , tych grup będzie kilkadziesiąt tysięcy - maksymalnie zagnieżdżone do 4 poziomu...)

Proszę o jakieś wskazówki.
Osobiście idę w stronę
  1. SELECT g.id , g1.id , g2.id , g3.id FROM grupa g LEFT JOIN (SELECT g1.id FROM grupa WHERE g1.grupa=g.grupa_glowna ORDER BY g1.nazwa) g1 ON g1.grupa=g.grupa_podstawowa
  2. LEFT JOIN (SELECT g2.id ...

Powtórzony zabieg łączenia 4 razy... Ale nie wiem jak się to faktycznie sprawdzi smile.gif

Będę to testował a między czasie sprawdzał czy macie jakieś inne pomysły...

Pozdrawiam.

Ps. Proszę nie pisać rozwiązania rozbitego na kilka zapytań całkowicie osobnych bo to już dawno mam smile.gif


EDIT---------------------


Rozwiązanie moje problemu, lecz nie wiem czy to będzie wystarczająco dobre...

  1. SELECT p1.nazwa , p2.p2n , p3.p3n FROM pozycje p1
  2. LEFT JOIN (SELECT p2.id , p2.nazwa p2n , p2.poz p2p , p2.grupa_podstawowa gp2 , p2.grupa p2g FROM pozycje p2 ) p2 ON p2.gp2=p1.grupa AND p2.gp2!=p2.p2g
  3. LEFT JOIN (SELECT p3.id , p3.nazwa p3n , p3.po p3p , p3.grupa p3g , p3.grupa_podstawowa gp3 FROM pozycje p3) p3 ON p2.m2g=p3.gp3 AND p3.gp3!=p3.p3g
  4. LEFT JOIN (SELECT p4.id , p4.nazwa p4n , p4.poz p4p , p4.grupa p4g , p4.grupa_podstawowa gp4 FROM pozycje p4) p4 ON p3.m3g=p4.gp4 AND p4.gp4!=p4.p4g
  5. ORDER BY p1.poz , p1.nazwa , p2p , p2n , p3p , p3n , p4p , p4n
john_doe
rozwiązanie nie jest optymalne bo co jeśli zagłebisz się dalej.
Potrzebujesz napisać funkcję rekurencyjną, która będzie wykonywać jedno zapytanie ( nadal rozwiązanie nie-super optymalne )
Napisałem kiedyś coś takiego w Codeigniter, miałem podobną strukturę tabeli ( rodzić, dzieci .... ) Przeanalizuj to może Ci pomoże.
  1. public function create_group( $parent, $level )
  2. {
  3. $menu = '';
  4. //error_reporting(E_ALL ^ E_NOTICE);
  5.  
  6. $CI =& get_instance();
  7.  
  8. $query = $CI->db->query("SELECT a.id, a.label, a.link, Deriv1.Count FROM `menu` a
  9. LEFT OUTER JOIN (
  10.  
  11. SELECT parent, COUNT(*) AS Count FROM `menu` GROUP BY parent
  12.  
  13. ) Deriv1 ON a.id = Deriv1.parent WHERE a.parent = " . $parent);
  14.  
  15. $menu .= "<ul id='nav'>";
  16.  
  17.  
  18. foreach($query->result() as $position)
  19. {
  20. if($position->Count > 0) {
  21.  
  22. if($level == 1)
  23. {
  24. $menu .= "<li><a href='" . $position->link . "'>" . $position->label . "</a>";
  25. }else $menu .= "<li><a href='" . $position->link . "'>" . $position->label . "</a>";
  26.  
  27. $menu .= $this->create_group($position->id, $level + 1);
  28.  
  29. $menu .= "</li>";
  30.  
  31. }elseif($position->Count == 0) {
  32.  
  33. $menu .= "<li><a href='" . base_url() . $position->link . "'>" . $position->label . "</a></li>";
  34.  
  35. }else;
  36.  
  37. }
  38.  
  39. $menu .= "</ul>";
  40.  
  41. return $menu;
  42. }
Prezi2907
Witam

Dzięki za info ale jak mówiłem rozwiązanie powtarzanego zapytania nie daje mi zamierzonych efektów... Moje rozwiązanie daje mi możliwość dodawani poziomów tylko i wyłącznie dodając kolejnych left join z selectem...

chciałem to jeszcze na unionach rozwalić (bo już miałem coś takiego) ale to nadal takie dość dziwne rozwiązanie...

Dzięki mimo to za pomoc. Do jutra postaram się dać odpowiedź co udało mi się zdziałać.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.