Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL][PHP] Sortowanie wg. 2 kryteriów
qweluke
post 14.04.2010, 22:00:08
Post #1





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


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

Ten post edytował qweluke 14.04.2010, 22:00:52
Go to the top of the page
+Quote Post
pedro84
post 14.04.2010, 22:07:11
Post #2





Grupa: Nieautoryzowani
Postów: 2 249
Pomógł: 305
Dołączył: 2.10.2006

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


Proszę:
Kod
ORDER BY xxx.aaa DESC, yyy.bbb ASC


W Google byś znalazł.

Ten post edytował pedro84 14.04.2010, 22:07:28


--------------------
Google knows the answer...
Go to the top of the page
+Quote Post
qweluke
post 14.04.2010, 22:27:39
Post #3





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


  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

Ten post edytował qweluke 14.04.2010, 22:28:15
Go to the top of the page
+Quote Post
pedro84
post 14.04.2010, 22:30:23
Post #4





Grupa: Nieautoryzowani
Postów: 2 249
Pomógł: 305
Dołączył: 2.10.2006

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


Dziwisz się?

  1. SELECT * FROM `xxx`, `yyy` WHERE xxx.id_uzytkownika=yyy.id ORDER BY xxx.id_xxx DESC, yyy.nazwisko ASC LIMIT 5


--------------------
Google knows the answer...
Go to the top of the page
+Quote Post
qweluke
post 14.04.2010, 22:38:21
Post #5





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


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?>
Go to the top of the page
+Quote Post
mortus
post 14.04.2010, 23:29:53
Post #6





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


  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
Go to the top of the page
+Quote Post
qweluke
post 14.04.2010, 23:51:29
Post #7





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


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 :/
Go to the top of the page
+Quote Post
mortus
post 15.04.2010, 06:03:50
Post #8





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


Zrób dump-a bazy danych, albo zaprezentuj strukturę tabel i co ważniejsze wklej tutaj odpowiedni fragment kodu +/- kilka linijek.
Go to the top of the page
+Quote Post
qweluke
post 15.04.2010, 08:48:51
Post #9





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


  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.
Go to the top of the page
+Quote Post
mortus
post 15.04.2010, 09:37:21
Post #10





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


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?
Go to the top of the page
+Quote Post
qweluke
post 15.04.2010, 09:49:26
Post #11





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


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)

Ten post edytował qweluke 15.04.2010, 09:53:18
Go to the top of the page
+Quote Post
mortus
post 15.04.2010, 10:04:10
Post #12





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


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.
Go to the top of the page
+Quote Post
qweluke
post 15.04.2010, 10:09:29
Post #13





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


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?

Ten post edytował qweluke 15.04.2010, 10:19:28
Go to the top of the page
+Quote Post
mortus
post 15.04.2010, 10:33:56
Post #14





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


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.
Go to the top of the page
+Quote Post
qweluke
post 18.04.2010, 08:49:25
Post #15





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


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? :/

Ten post edytował qweluke 17.04.2010, 22:19:19
Go to the top of the page
+Quote Post
pedro84
post 18.04.2010, 09:54:33
Post #16





Grupa: Nieautoryzowani
Postów: 2 249
Pomógł: 305
Dołączył: 2.10.2006

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


Poczytaj o GROUP BY, dużo informacji masz...na tym forum. Klik


--------------------
Google knows the answer...
Go to the top of the page
+Quote Post
qweluke
post 22.04.2010, 09:49:14
Post #17





Grupa: Zarejestrowani
Postów: 87
Pomógł: 0
Dołączył: 25.03.2010
Skąd: Radom

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


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

Ten post edytował qweluke 22.04.2010, 16:53:17
Go to the top of the page
+Quote Post
mortus
post 22.04.2010, 20:58:31
Post #18





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


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

Ten post edytował mortus 22.04.2010, 21:08:47
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 00:17