Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Sortowanie wg. 2 kryteriów
Forum PHP.pl > Forum > Przedszkole
qweluke
Panowie,

jak moge posortować wyniki pobrane przez zapytanie mysql?
  1. SELECT * FROM `xxx`, `yyy` WHERE xxx.id_uzytkownika=yyy.id ORDER BY xxx.id_uzytkownika DESC LIMIT 5


obecnie mam cos takiego, teraz to co otrzymałe chce posortować wg

yyy.zzz czyli powinienem jakoś dodać do zapytania SQL
  1. ORDER BY yyy.zzz ASC

ale już raz to występuje.

Wiem, ze jesteście w stanie mi pomóc smile.gif
pedro84
Proszę:
Kod
ORDER BY xxx.aaa DESC, yyy.bbb ASC


W Google byś znalazł.
qweluke
  1. SELECT * FROM `xxx`, `yyy` WHERE xxx.id_uzytkownika=yyy.id ORDER BY xxx.id_xxx DESC LIMIT 5, yyy.nazwisko ASC


nie działa
pedro84
Dziwisz się?

  1. SELECT * FROM `xxx`, `yyy` WHERE xxx.id_uzytkownika=yyy.id ORDER BY xxx.id_xxx DESC, yyy.nazwisko ASC LIMIT 5
qweluke
tak tez probowalem i tez nic z tego.

poza tym, limit musi byc przy pierwszym sortowaniu (DESC) ponieważ tym sposobem wybieram najstarsze (najaktualniejsze) dane z bazy.

w bazie jest kilkadziesiąt rekordów które są przypisane do pięciu użytkowników i najpierw sortuje je aby otrzymać najnowsze u samej góry ( ORDER BY xxx.id_xxx DESC) potem wybieram te tylko te nowe (LIMIT 5) i na końcu sortuję po użytkowniku (nazwisku).


jest jakieś inne rozwiązanie tego problemu?>
mortus
  1. SELECT * FROM (SELECT * FROM xxx, yyy WHERE xxx.id_uzytkownika=yyy.id ORDER BY xxx.id_xxx DESC LIMIT 5) AS last_five ORDER BY nazwisko ASC
qweluke
przy takim zapytaniu wywala błąd

  1. Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given



nie mam na to zielonego pomysły :/
mortus
Zrób dump-a bazy danych, albo zaprezentuj strukturę tabel i co ważniejsze wklej tutaj odpowiedni fragment kodu +/- kilka linijek.
qweluke
  1. CREATE TABLE `xxx` (
  2. `edycja` char(1) COLLATE utf8_unicode_ci NOT NULL,
  3. `id_uzytkownika` int(5) UNSIGNED NOT NULL,
  4. `id_grafiku` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  5. `miesiac` tinyint(2) UNSIGNED NOT NULL,
  6. `rok` smallint(4) UNSIGNED NOT NULL,
  7. `1` char(4) COLLATE utf8_unicode_ci NOT NULL,
  8. `2` char(4) COLLATE utf8_unicode_ci NOT NULL,
  9. `3` char(4) COLLATE utf8_unicode_ci NOT NULL,
  10. `4` char(4) COLLATE utf8_unicode_ci NOT NULL,
  11. `5` char(4) COLLATE utf8_unicode_ci NOT NULL,
  12. `6` char(4) COLLATE utf8_unicode_ci NOT NULL,
  13. `aktualizacja` text COLLATE utf8_unicode_ci NOT NULL,
  14. PRIMARY KEY (`id_grafiku`)
  15. ) ENGINE=MyISAM AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci



Tak wyglada tabela xxx.

Na czerwono zaznaczyłem powtarzające się rekordy, na zielono autoinkrementowane id aby wiedzieć który z tych rekordów (zaznaczonych na czerwono) jest najnowszy (najstarszy).

Chcę wybrać te X użytkowników dla którego id_grafiku jest najstarsze. (gdzie w chwili obecnej X=5, to ilość użytkowników w bazie)

np.
teraz uzytkownik o ID 1 ma dwa wpisy, id_grafiku 2 oraz 12. Chcę wybrać tylko tą 12.
mortus
Cytat
teraz uzytkownik o ID 1 ma dwa wpisy, id_grafiku 2 oraz 12. Chcę wybrać tylko tą 12
  1. SELECT * FROM xxx WHERE id_uzytkownika=1 ORDER BY id_grafiku DESC LIMIT 0, 1
Nie do końca Cię rozumiem, chcesz wybrać najnowsze rekordy z tabeli xxx dla każdego użytkownika z osobna, czy może 5 użytkowników, którzy zostali jako ostatni dopisani do grafiku?
qweluke
z tabeli XXX chce wybrać najnowsze rekordy dla każdego użytkownika z osobna ale jednym zapytaniem a następnie te dane które wybrałem chcę jeszcze posortowac po nazwisku.

chodzi o rekordy zaznaczone w niebieskim kwadracie


czyli inaczej mówiąc, chcę połaczyć te dwa zapytania SQL w jedno:

  1. SELECT * FROM `xxx`, `uzytkownicy` WHERE xxx.id_uzytkownika=uzytkownicy.id ORDER BY xxx.id_grafiku DESC LIMIT 5

(wybieram te najnowsze które mnie interesują)


  1. SELECT * FROM `xxx`, `uzytkownicy` WHERE xxx.id_uzytkownika=uzytkownicy.id ORDER BY uzytkownicy.nazwisko ASC

(a tym zapytaniem sortuje te dane wg. nazwiska, z tym, że to zapytanie zwraca mi wszystkie rekordy a nie te najnowsze)
mortus
A takie zapytanie nie działa?
  1. SELECT * FROM (SELECT * FROM `xxx`, `uzytkownicy` WHERE xxx.id_uzytkownika=uzytkownicy.id ORDER BY xxx.id_grafiku DESC LIMIT 5) AS last_five ORDER BY uzytkownicy.nazwisko ASC;
Jeśli nie działa to spróbuj takim kodem:
  1. mysql_query("POWYŻSZE ZAPYTANIE") or die(mysql_error());
W przypadku niepowodzenia dostaniesz komunikat błędu. Wklej go tutaj.
qweluke
nooo, w koncu zadziałało ale w takiej postaci

  1. SELECT * FROM (SELECT * FROM `xxx`, `uzytkownicy` WHERE xxx.id_uzytkownika=uzytkownicy.id ORDER BY xxx.id_grafiku DESC LIMIT 5) AS last_five ORDER BY nazwisko ASC;


dziękuje Ci bardzo za pomoc, bez Ciebie bym sobie nie poradził smile.gif


jeszcze szybkie pytanie "AS last_five" co robi?

jeśli rekordów nei będzie 5 a 80, także zadziała?
mortus
AS last_five nadaje alias tymczasowej tabeli zwróconej przez SELECT w nawiasach i musimy taki alias przypisać jeśli chcemy użyć zapytania w stylu
  1. SELECT * FROM (SELECT ...)
Jak bedzie 80 rekordów, to również zadziała.
qweluke
działa świetnie, tylko że pojawił się jeszcze jeden problem.

Poprzez zapytanie
  1. SELECT *
  2. FROM (
  3.  
  4. SELECT *
  5. FROM `xxx` , `uzytkownicy`
  6. WHERE xxx.id_uzytkownika = uzytkownicy.id
  7. ORDER BY xxx.id_grafiku DESC
  8. LIMIT 6
  9. ) AS last_five
  10. ORDER BY nazwisko ASC


wyświetla mi 2x usera o ID 6 ponieważ ma dwa najstarsze wpisy (id_grafiku 18 i 17) a przez to, user o ID1 nie jest wyświetlany ponieważ limit jest na 6 (zmienna ilosc uzytkownikow, jeśli uzytkowników będzie 20, limit będzie 20) więc zwiększenie limitu na 7 odpada.


Muszę przerobić to zapytanie tak, aby wybierało łącznie 6 wpisów ale tylko jeden wpis dla jednego użytkownika gdzie id_grafiku jest najstrasze, a następnie sortował wynik po nazwisku.

Ktoś wie jak to zrobić?

naprawdę nikt nie wie? :/
pedro84
Poczytaj o GROUP BY, dużo informacji masz...na tym forum. Klik
qweluke
Panowie,

nie potrafie sobie z tym poradzić :/

za każdym razem nie wybiera mi wszystkich danych. gdy uzyje

  1. SELECT *
  2. FROM (
  3.  
  4. SELECT *
  5. FROM `xxx` , `uzytkownicy`
  6. WHERE xxx.id_uzytkownika = uzytkownicy.id
  7. ORDER BY xxx.id_grafiku DESC
  8. LIMIT 6
  9. ) AS last_five
  10. ORDER BY nazwisko ASC

wyświetla mi 2 razy użytkownika o ID 6, ponieważ posiada dwa najstarsze rekordy (xxx.id_grafiku=18 i 17)

Natomiast przy zapytaniu z grupowaniem

  1. SELECT * FROM (SELECT * FROM `xxx`, `uzytkownicy` WHERE xxx.id_uzytkownika=uzytkownicy.id GROUP BY xxx.id_uzytkownika ORDER BY xxx.id_grafiku DESC LIMIT 6) AS last_five ORDER BY nazwisko ASC

wyświetla mi pierwsze 6 rekordów, nawet jesli użyje

  1. SELECT * FROM (SELECT * FROM `xxx`, `uzytkownicy` WHERE xxx.id_uzytkownika=uzytkownicy.id GROUP BY xxx.id_uzytkownika

to zwracany wynik jest taki sam

może ktos mnie nakierowac, co robie źle?


może to jeszcze lepiej naszkicuje mój problem/zapytanie:

wybierz po jednym najstarszym wpisie dla każdego z 6 użytkowników z tabeli xxx, uzytkownicy gdzie xxx.id_uzytkownika=uzytkownicy.id
mortus
Słowo wyjaśnienia. GROUP BY grupuje rekordy według wartości w danej kolumnie i na określonej grupie rekordów wykonuje zapytanie. My chcemy uzyskać najnowsze wpisy do grafiku dla każdego użytkownika z osobna. Jak się za to zabrać? Przede wszystkim grupujemy rekordy według identyfikatora użytkownika, a to w praktyce oznacza, że zapytanie zostanie wykonane dla każdej grupy rekordów i w poszczególnej grupie rekordów wszystkie rekordy "należą" do danego użytkownika. Niestety pobrany zostanie tylko jeden rekord z każdej grupy, ten pierwszy w kolejności w domyślnym sortowaniu. Jeżeli zatem chcemy wybrać te najnowsze rekordy z grafiku, to musimy najpierw posortować rekordy w odpowiedniej kolejności, czyli malejąco po id_grafiku. Teraz zapytanie:
  1. SELECT * FROM (SELECT * FROM xxx ORDER BY id_grafiku DESC) AS posortowane GROUP BY posortowane.id_uzytkownika;
Teraz dołączmy do tego wszystkie informacje o użytkowniku:
  1. SELECT * FROM (SELECT * FROM xxx ORDER BY id_grafiku DESC) AS posortowane, uzytkownicy WHERE uzytkownicy.id=posortowane.id_uzytkownika GROUP BY posortowane.id_uzytkownika;
Zapytanie takie zwróci wszystkie kolumny z tabeli xxx i wszystkie kolumny z tabeli uzytkownicy, zatem na pewno w wyniku pojawią się dwie kolumny o takiej samej zawartości poszczególnych wierszy (będą to kolumny z identyfikatorami użytkowników z obu tabel). Aby tego uniknąć musielibyśmy określić jakie dokładnie kolumny chcemy pobrać. Pozostaje jeszcze kwestia sortowania. Tak uzyskane wyniki są posortowane według id użytkownika począwszy od najmniejszego do największego. Tę kolejność możemy odwrócić dokładając do GROUP BY słowo DESC:
SELECT ... GROUP BY posortowane.id_uzytkownika DESC
Możemy również wymusić, aby wyniki były posortowane według id_grafiku. Dopisujemy na końcu
ORDER BY posortowane.id_grafiku
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.