Skocz do zawartości

[MYSQL] - Sortowanie


qwertyuiop

Rekomendowane odpowiedzi

Baza wygląda tak:

| menu_id | menu_pid | menu_nazwa | menu_waga |

gdzie:

- menu_id - unikalne id kategorii;

- menu_pid - jest dany rekord jest kategorią to menu_pid = menu_id, jeśli jest podkategorią to menu_pid zawiera menu_id kategorii dla której jest podkategorią ;

- menu_nazwa - nazwa jak nazwa, nic specjalnego !!!;

- menu_waga - waga elementu menu (-10...10);

Teraz mam pytanie (zwiesiłem się, chyba za długo nad tym siedzę), jak to posortować za pomocą zapytania MySQL (później idzie to do grida), aby otrzymać coś takiego:

Menu 2 (waga 3)
 - podmenu 1  (waga -10)
 - podmenu 2  (waga -10)
 - podmenu 4  (waga -10)
 - podmenu 3  (waga -9)
Menu 3 (waga 3)
 - podmenu 1
 - podmenu 2
 - podmenu 3
Menu 1 (waga 5)
 - podmenu 1
 - podmenu 2
 - podmenu 3

Czyli:

|   menu_id  |   menu_pid	 |  menu_nazwa   |  menu_waga   |
|	  1	   |	   1		|	  Menu 2	   |	  3	 |
|	  7	   |	   1		|	 podmenu 1	 |	-10	 |
|	  12	  |	   1		|	 podmenu 2	 |	-10	 |
|	  22	  |	   1		|	 podmenu 4	 |	-10	 |
|	  56	  |	   1		|	 podmenu 3	 |	-9	  |
|	  7	   |	   7		|	  Menu 2	   |	  3	 |
|	  21	  |	   7		|	 podmenu 1	 |	-10	 |

Sortowanie powinno się odbywać po wadze pozycji, a jeśli mają taką samą wagę to alfabetycznie.

Z góry dzięki za pomoc.

"Dopiero gdy wolna wola znowu zaskoczyła, przerwali bieg po torze przeszkód ich własnej konstrukcji."

Odnośnik do komentarza
Udostępnij na innych stronach

Da się to zrobić bez procedur (menu trzypoziomowe też, chociaż nie próbowałem:) )

SELECT IF(b.id = b.podmenu_id, 0 , 1) as poziom, b.id as id, b.podmenu_id as podmenu_id, b.nazwa as nazwa, b.waga as waga FROM menu as a
INNER JOIN menu as b
ON a.id = b.podmenu_id
WHERE a.id = a.podmenu_id
ORDER BY a.waga DESC, a.nazwa ASC, b.waga DESC, b.nazwa ASC

A co do tabeli - nazwy kolumn nie powinny duplikować nazwy tabeli, potem to wprowadza chaos w kodzie i w kluczach obcych (kiedy na przykład kojarzysz usera z komentarzami i piszesz FK do tabeli comment: user_user_id).

Odnośnik do komentarza
Udostępnij na innych stronach

Większość menu ma to do siebie, że zmienia się dość rzadko więc można zastosować cachowanie

Ja bym nie zawracał sobie głowy z optymalnym czy jednozdaniowym zapytaniem ale napisalbym skrypt

w php ktory generuje dane wyjsciowe (xml,html,txt,... - jak wygodniej) i uruchamial go przy zmianie w tablicy.

Takie rozwiązanie ma zalety następujące:

cachowanie - odciązenie bazy i procesora i to bardzo powazne

prosciej zaimplementowac - jak widac nie trzeba glowkowac nad skomplikowany a i pewnie malo wydajnym w efekcie zapytaniem.

Wady:

Wiecej pisaniny (ale to wada jednorazowa)

wiecej kodu i zasobow - wada do pominiecia bo ilez to moze byc 1,2 kb?

No chyba, ze menu zmienia ci sie co kilka sekund (malo prawdopodobne) albo, co bardziej prawdopodobne, jest zalezne od uzytkownika, konfiguracji - bedzie to zawsze liczba skonczona i mozna wygenerowac od razu N plikow wyjsciowych.

Odnośnik do komentarza
Udostępnij na innych stronach

Dzięki za odpowiedź, działa częściowo, ale dam sobie rade.

Co do pozostałych sugestii, to są jak najbardziej słuszne, jednak na takim zapytaniu zależało mi z powodu środowiska (framework i grid). Normalnie rozwiązał bym to klasą, ale tutaj idzie do edytora menu opartego na gridzie. Jeszcze raz dzięki za pomoc, bo się zapętliłem na tym problemie wczoraj. Frameworki są jak komputery, ułatwiają pracę której by nie było bez nich. :crazy:

"Dopiero gdy wolna wola znowu zaskoczyła, przerwali bieg po torze przeszkód ich własnej konstrukcji."

Odnośnik do komentarza
Udostępnij na innych stronach

A taka koncepcja ?

Dodatkowa kolumna ?

Zalety: nieograniczona ilośc poziomów :crazy:

|	 menu_id  |   menu_pid	 |  menu_nazwa	   |  menu_waga | PATH
|	  1	   |	   0		|	  Menu 2	   |	  3	 | /001
|	  7	   |	   1		|	 podmenu 1	 |	-10	 | /001/007
|	  12	  |	   1		|	 podmenu 2	 |	-10	 | /001/012
|	  22	  |	   1		|	 podmenu 4	 |	-10	 | /001/022
|	  56	  |	   1		|	 podmenu 3	 |	-9	  | /001/056
|	  7	   |	   0		|	  Menu 2	   |	  3	 | /007
|	  21	  |	   7		|	 podmenu 1	 |	-10	 | /007/021

Odnośnik do komentarza
Udostępnij na innych stronach

@Papieros: Zapytanie raczej należy do tych prostych niż do tych skomplikowanych, fajnie jest czasami popisać w czymś takim jak prolog.

Co będzie szybsze? Bez dodatkowej implementacji cache na 100% ten SQL bo cache w SQL już jest;) To zapytanie trafi do QC SQL'a i się wykona raz bez dodatkowego pisania.

Co do cache na plikach to BARDZO ZŁY pomysł. PHP nie obsługuje żadnego mechanizmu kontroli wątków (semaforów czy sekcji krytycznych). Przy odpowiednio wysokim loadzie taki cache się wysypie i albo będzie zwracał pustą zawartość albo komunikaty błędów. (google -> race conditions).

Cache można zaimplementować właśnie na mySQL (wspiera operacje atomowe a innoDB nawet full acid i atomowe transakcje). Albo na memcached, to narzędzie specjalnie do tego celu które też można używać "bezpiecznie" nawet przy wysokim loadzie i wielu rdzeniach. Błędy powodowane przez cache na plikach nie będą się zdarzały często i pewnie w większości przypadków programista w ogóle ich nie zauważy, większość użytkowników też - co nie zmienia faktu, że to niepoprawny kod zawierający błędy.

Odnośnik do komentarza
Udostępnij na innych stronach

A tak przy okazji o drzewkach w DB mozna sobie poczytać tutaj:

https://www.depesz.com/various/various-sqltrees.php

Co do tego cache na plikach to aż tak bym nie krytykował tej metody.

Rozwiązanie jak każde inne, byle być świadomym niebezpieczeństw.

Z miła chęcią poczytał bym o jakimś porównaniu cache na plikach i bazie a szczególnie benchmarki.

Odnośnik do komentarza
Udostępnij na innych stronach

sławek22, przyznam się, że specjalnie się nie przyglądałem problemowi qwertuiop'a ale robiłem kiedyś wielopoziomowe menu i zrobiłem cachowanie plikami - działa cacy.

co do semaforów i sekcji krytycznych to w przypadku rzadko zmienianych menu bym nie przesadzal - nie widze potrzeby stosowania takich armat.

o cach'u w mySQL'u nie wiele wiem ale wydaje mi się, że cache owszem jest ale czas cachowania nie jest zbyt dlugi w porownaniu z szybkoscią zmian struktury menu więc ( nie dam sobie ręki uciąć) ale wydaje mi sie, ze jednak cachowanie plikami bedzie wydajniejsze nawet przy duzym loadzie.

Odnośnik do komentarza
Udostępnij na innych stronach

Wszystko zależy od projektu, sił i środków, a co najważniejsze od wiedzy i kompetencji :(. Każdy programista (doświadczony) ma swój warsztat, bazę bibliotek, sprawdzone rozwiązania itp, co często determinuje podejście do projektu (szczególnie przy tych mniejszych projektach). Konkretne rozwiązania rozpatrywał bym raczej w ramach danego projektu i jego warunkach. Oczywiście mając na względzie wzorce i dobre praktyki.

"Dopiero gdy wolna wola znowu zaskoczyła, przerwali bieg po torze przeszkód ich własnej konstrukcji."

Odnośnik do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę. Warunki użytkowania Polityka prywatności