Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL]Niepoprawne sortowanie tabeli
Demoneos
post 16.05.2012, 15:12:17
Post #1





Grupa: Zarejestrowani
Postów: 149
Pomógł: 0
Dołączył: 26.02.2008

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


Sortuję tabelę wg. pola zawierającego liczby (sumy pieniędzy) w takim formacie jak ta przykładowa liczba: 4 381 532.50
Sortowanie nie wykonuje się tak jakbym tego chciał:
Cytat
4 061 206.20
4 029 104.20
4 016 132.10
33 787 496.10
3 972 404.10
3 970 208.20

czyli mniejsze kwoty są przed większymi.

Co należałoby zrobić, żeby sortowanie było poprawne? Może zmienić jakoś format tych liczb?

Ten post edytował Demoneos 16.05.2012, 15:12:53


--------------------
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 8)
bpskiba
post 16.05.2012, 15:35:50
Post #2





Grupa: Zarejestrowani
Postów: 340
Pomógł: 49
Dołączył: 3.07.2009
Skąd: Rzeszów

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


Przechowujesz liczby w polu typu tekstowego więc sortowanie nie wychodzi tak, jak oczekujesz. Problemem są spacje

może
  1. SELECT REPLACE(kolumna," ","")*1,kolumna FROM tabela ORDER BY 1


Ten post edytował bpskiba 16.05.2012, 15:38:20
Go to the top of the page
+Quote Post
Demoneos
post 16.05.2012, 17:17:46
Post #3





Grupa: Zarejestrowani
Postów: 149
Pomógł: 0
Dołączył: 26.02.2008

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


Trop jest chyba dobry, ale nie pomogło. Stworzyłem takie zapytanie:
  1. SELECT REPLACE(REPLACE(kolumna,' ',''),'.','') AS aaaa FROM $this->tabela ORDER BY aaaa DESC


czyli pozbyłem się i spacji i nawet kropki, a sortuje wciąż niepoprawnie:

Cytat
337956400

3378749610

337471590


kolumna na format varchar(20), więc może tu jest problem, że to pole tekstowe i może w takiej sytuacji trzeba jakoś inaczej sortować?

Ten post edytował Demoneos 16.05.2012, 17:18:45


--------------------
Go to the top of the page
+Quote Post
lobopol
post 16.05.2012, 18:33:52
Post #4





Grupa: Zarejestrowani
Postów: 1 729
Pomógł: 346
Dołączył: 4.04.2009

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


Nie powinno się trzymać liczb w polach tekstowych, skoro to są float to trzymaj je jako floaty a nie varchary. Czyli float/double/etc.


--------------------
Go to the top of the page
+Quote Post
miniol
post 16.05.2012, 20:44:17
Post #5





Grupa: Zarejestrowani
Postów: 84
Pomógł: 4
Dołączył: 25.03.2011

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


Sortowanie tekstu zawsze jest alfabetycznie, a nie numerycznie. Tak więc sortując alfabetycznie zawsze '152454' będzie przed '4', bo sortowanie odbywa się znak po znaku. Zamień sobie te dane na integer i będziesz mógł sortować je numerycznie.
Go to the top of the page
+Quote Post
bostaf
post 17.05.2012, 07:30:17
Post #6





Grupa: Zarejestrowani
Postów: 374
Pomógł: 79
Dołączył: 6.04.2010
Skąd: Ostrów Wielkopolski

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


To co koledzy napisali wcześniej o przechowywaniu liczb w odpowiednim formacie jest najlepszym rozwiązaniem.
Ale jeśli z jakiegoś powodu nie możesz zmienić typu danych w kolumnie, możesz skorzystać z funkcji CAST() i spreparować swoje zapytanie w taki sposób:
  1. SELECT CAST(REPLACE(kolumna,' ','') AS DECIMAL(65,2)) AS aaaa
  2. FROM $this->tabela ORDER BY aaaa DESC

Typ DECIMAL jest dostępny od wersji MySQL 5.0.8. Jeśli masz wcześniejszą wersję, to musisz "castować" jako SIGNED albo UNSIGNED, tracąc to co jest po przecinku.
Go to the top of the page
+Quote Post
Demoneos
post 17.05.2012, 19:31:51
Post #7





Grupa: Zarejestrowani
Postów: 149
Pomógł: 0
Dołączył: 26.02.2008

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


bostaf, Twoje zapytanie działa bardzo dobrze, ale jaki ma wpływ na szybkość wykonania zapytania? Obecnie wykonuje to zapytanie na tabeli liczącej około 800 wierszy i wykonuje się bardzo szybko, ale jak będzie przy dużo większych tabelach?


--------------------
Go to the top of the page
+Quote Post
lobopol
post 17.05.2012, 19:38:40
Post #8





Grupa: Zarejestrowani
Postów: 1 729
Pomógł: 346
Dołączył: 4.04.2009

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


Oczywiście wolniej, nawet sporo w końcu musisz przerabiać naprawdę dużo danych, użyj odpowiednich typów pól i je odpowiednio poindeksuj, a zobaczysz dużą różnicę i nie będziesz się musiał martwić poprawnością typów danych w bazie.


--------------------
Go to the top of the page
+Quote Post
bostaf
post 17.05.2012, 21:34:08
Post #9





Grupa: Zarejestrowani
Postów: 374
Pomógł: 79
Dołączył: 6.04.2010
Skąd: Ostrów Wielkopolski

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


Cytat(Demoneos @ 17.05.2012, 20:31:51 ) *
jak będzie przy dużo większych tabelach?

CAST() jest funkcją, która przetwarza dane - każde przetworzenie to dodatkowy czas. Czas wykonania zapytania będzie rósł w postępie arytmetycznym, proporcjonalnie do ilości przetwarzanych danych.

Przetestowałem to zapytanie na tabeli z dwoma milionami rekordów (w drugim i trzecim przypadku bez CASTa oczywiście), z kolumną "kolumna" w trzech wariantach typu danych: VARCHAR(40), DECIMAL(40,2) i BIGINT(40). Takie były średnie czasy wykonania (10 prób dla każdego przypadku):
  1. kolumna jako VARCHAR(40): min. 23,275 sek., max. 25,615 sek.
  2. kolumna jako DECIMAL(40,2): min. 3,370 sek., max. 3,557 sek.
  3. kolumna jako BIGINT(40): min. 2,730 sek., max 2,824 sek.

Wnioski są oczywiste smile.gif No i testuj sam. Zrób na przykład test jak rodzaj silnika bazy wpływa na szybkość wykonania zapytania - w niektórych przypadkach MyISAM jest szybsze od InnoDB, w innych odwrotnie.
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 - 09:16