Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Zapytanie SQL, Dość zagadkowe zapytanie
Prezi2907
post
Post #1





Grupa: Zarejestrowani
Postów: 107
Pomógł: 4
Dołączył: 11.08.2010
Skąd: Inowrocław

Ostrzeżenie: (10%)
X----


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 (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/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


Ten post edytował Prezi2907 19.12.2012, 15:02:29
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
john_doe
post
Post #2





Grupa: Zarejestrowani
Postów: 873
Pomógł: 25
Dołączył: 24.07.2005

Ostrzeżenie: (0%)
-----


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. }
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 13.10.2025 - 07:51