Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Sortowanie wg konkretnych wartości
Forum PHP.pl > Forum > Bazy danych > MySQL
MistrzHTML
Witam.

Załóżmy, że mamy prościutką tabelę danych przechowującą ludzi, każdy z unikalnym numerem ID.

Załóżmy dodatkowo, że tabela ta ma wiele rekordów. Chcemy posortować ją wg dowolnej kolejności - brzmi to dziwnie, ale takie rozwiązanie jest mi potrzebne - np. wg numerów: 6,8,2,9,1,100,200,542,142, a dalej już np. rosnąco.

Czy jest na to jakieś bardziej elegancki sposób niż tworzenie ogromnego zapytania z wieloma słówkami UNION? Dla mnie nie jest to problemem wygenerować takowe dynamicznie, ale czy jest prostszy, może mniej obciążający bazę sposób na takowe zapytanie?
Indeo
Tak jest elegancki sposób:

Np niech będzie zmienna x będąca funkcją wieku (tu id) i po niej będziemy chcieli sortować:

  1. SELECT id,
  2. case
  3. when id=4 then 1
  4. when id=8 then 2
  5. else id
  6. end AS x
  7. FROM ludzie ORDER BY x ASC


jak widzisz to zapytanie tworzy sobie nową zmienną w której wartości kolumny id są przewartościowane wg instrukcji case i wg tej zmiennej sortujesz.
MistrzHTML
Dobry pomysł, ale zapytanie nie zadziała do końca tak jak powinno. Jeżeli przypisze tej zmiennej konkretne wartości dla wybranych id, a pozostałe wypełni samym id, to oryginalne numery id, które miały zostać wybrane po tych konkretnych wartościach, "wepchną się" między nie. Jeżeli na początku chcę mieć rekord o numerze 7, a potem 4 zakładając, że mam w bazie oryginalne numery od 1 wzwyż, to otrzymam taki wynik:

7 (x=1), 1 (x=1), 4 (x=2), 2 (x=2) lub 1,7,4,2 lub 7,1,2,4 lub 1,7,4,2 - zależy od kolejności wpisów w bazie.

Ja chciałbym, by rekordy z numerami 7 i 4 wskoczyły przed wszystkie inne.

----------------------------------------------------------------------------------------------------

02:01

Właśnie odkryłem, że działa zapis

  1. SELECT imie,nazwisko FROM ludzie ORDER BY nr=7,nr=4,nr ASC


rolleyes.gif

Co dziwne, wyświetla rekordy o numerach 4 i 7 na samym dole wyników (7 to ostatni zwrócony rekord). Wyniki w pożądanej kolejności zwraca zapytanie:

  1. SELECT imie,nazwisko FROM ludzie ORDER BY nr=7 DESC,nr=4 DESC,nr ASC


Dziwne, ale prawdziwe tongue.gif
Indeo
  1. SELECT id,
  2. case
  3. when id=4 then -99999
  4. when id=8 then -99998
  5. else id
  6. end AS x
  7. FROM ludzie ORDER BY x ASC



i już sie nie wcisną winksmiley.jpg


Mój sposób pozwala na budowanie bardzo złożonej topologii warunków bo przecież mogłoby być:

....
when kobieta='yes' and wiek between (18 and 60) then 'kobieta_pracujaca'
when userid=1 then 'jakis_user'
else costam
....
czyli kolejne warianty mogą składać sie z dowonych wyrażeń i w momencie natrafienia na pierwsze spełnione (prawdziwe) porównanie mechanizm pomija kolejne porównania i przechodzi do porównywania kolejnego rekordu. Co więcej - można sobie po takiej zdefiniowanej zmiennej grupować, sumować itd
A w sort orderingu byłoby to trudne do zapisania winksmiley.jpg
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-2025 Invision Power Services, Inc.