SQL do porządkowania według numeru - 1,2,3,4 itd. Zamiast 1,10,11,12

86

Próbuję uporządkować według kolumny liczb w mojej bazie danych, która ma wartości 1-999

Kiedy używam

ORDER_BY registration_no ASC

Dostaję….

1
101
102
103
104
105
106
107
108
109
11
110
Etc…

Wygląda więc na to, że jest to kolejność według pierwszej cyfry, a nie liczby.

Czy ktoś wie, jakiego języka SQL użyć, jeśli chcę to uporządkować według wartości? Więc 1,2,3,4,5,6itd

Konnor262
źródło
11
Twoja kolumna jest typu varchar, przez co masz do czynienia z takim zachowaniem.
Meherzad
jaki jest typ danych kolumny register_no?
Praveen Prasannan
9
Użyj, order by registration_no + 0 ascaby rozwiązać problem.
Meherzad
10
Nigdy nie należy przechowywać liczb w kolumnie znakowej. Twój problem jest bezpośrednim skutkiem tego błędu.
a_horse_with_no_name
Moja kolumna to Varchar, a dane, które przechowuję, to klasa 10 / klasa 9 / klasa 8. Teraz klasa 10 znajduje się przed klasą 8. Jak rozwiązać ten problem bez konieczności zajmowania się kolumną display_order?
Vishnoo Rath

Odpowiedzi:

139

Jednym ze sposobów uporządkowania według dodatnich liczb całkowitych, gdy są one przechowywane jako varchar, jest uporządkowanie najpierw według długości, a następnie według wartości:

order by len(registration_no), registration_no

Jest to szczególnie przydatne, gdy kolumna może zawierać wartości nienumeryczne.

Uwaga: w niektórych bazach danych length()zamiast funkcji można wywołać funkcję uzyskiwania długości łańcucha len().

Gordon Linoff
źródło
1
To nie zadziała we wszystkich przypadkach. Z góry na głowę, przypadki, które nie zadziałają, są połączeniami liczb całkowitych z; liczby ujemne, liczby z zerami na początku, liczby z ułamkami oraz słowa i liczby łącznie.
WonderWorker
10
@ Knickerless-Noggins. . . Przeczytaj pierwsze zdanie odpowiedzi. Myślę, że to całkiem jasne.
Gordon Linoff,
@GordonLinoff czy porządkowanie według tej samej kolumny dwa razy nie wymaga dużej mocy obliczeniowej i pamięci?
loneStar
@Achyuth. . . Liczba kluczy w jednym order byma niewielki wpływ na wydajność.
Gordon Linoff
1
W przypadku Oracle SQL użyj length()zamiastlen()
Stevoisiak
61
ORDER_BY cast(registration_no as unsigned) ASC

jawnie konwertuje wartość na liczbę. Inną możliwością osiągnięcia tego samego byłoby

ORDER_BY registration_no + 0 ASC

co wymusi niejawną rozmowę.

Właściwie powinieneś sprawdzić definicję tabeli i ją zmienić. Możesz zmienić typ danych w intten sposób

ALTER TABLE your_table MODIFY COLUMN registration_no int;
juergen d
źródło
13

Jeśli używasz SQL Server:

ORDER_BY cast(registration_no as int) ASC
IPOSTEDONCE
źródło
3
ORDER_BY cast(registration_no as unsigned) ASC

daje pożądany rezultat z ostrzeżeniami.

Dlatego lepiej iść

ORDER_BY registration_no + 0 ASC

aby uzyskać czysty wynik bez ostrzeżeń SQL.

priyanka
źródło
2

Zakładam, że typ kolumny to STRING (CHAR, VARCHAR itp.), A procedura sortowania sortuje ją jako ciąg. To, co musisz zrobić, to przekonwertować wartość na wartość liczbową. Sposób wykonania zależy od używanego systemu SQL.


źródło
1

Czasami po prostu nie masz wyboru, czy musisz przechowywać liczby zmieszane z tekstem. W jednej z naszych aplikacji host witryny internetowej, którego używamy w naszej witrynie handlu elektronicznego, dynamicznie usuwa filtry z list. Nie ma opcji sortowania według dowolnego pola poza wyświetlanym tekstem. Kiedy chcieliśmy, aby filtry składały się z listy zawierającej takie rzeczy jak od 2 "do 8" 9 "do 12" 13 "do 15" itd., Potrzebowaliśmy sortowania 2-9-13, a nie 13-2-9, jak będzie to miało miejsce w przypadku odczyt wartości liczbowych. Więc użyłem funkcji SQL Server Replicate wraz z długością najdłuższej liczby, aby dopełnić mniejsze liczby spacją wiodącą. Teraz 20 jest sortowane po 3 i tak dalej.

Pracowałem z widokiem, który podał mi minimalne i maksymalne długości, szerokości itp. Dla typu i klasy przedmiotu, a oto przykład tego, jak zrobiłem tekst. (LB n Low i LB n High to dolny i górny koniec 5 nawiasów długości.)

REPLICATE(' ', LEN(LB5Low) - LEN(LB1High)) + CONVERT(NVARCHAR(4), LB1High) + '" and Under' AS L1Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB2Low)) + CONVERT(NVARCHAR(4), LB2Low) + '" to ' + CONVERT(NVARCHAR(4), LB2High) + '"' AS L2Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB3Low)) + CONVERT(NVARCHAR(4), LB3Low) + '" to ' + CONVERT(NVARCHAR(4), LB3High) + '"' AS L3Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB4Low)) + CONVERT(NVARCHAR(4), LB4Low) + '" to ' + CONVERT(NVARCHAR(4), LB4High) + '"' AS L4Text,
CONVERT(NVARCHAR(4), LB5Low) + '" and Over' AS L5Text
Joey Morgan
źródło
1

Wolę robić „PAD” do danych. MySql nazywa to LPAD, ale możesz zrobić to samo w SQL Server.

ORDER BY  REPLACE(STR(ColName, 3), SPACE(1), '0') 

Ta formuła zapewni zera wiodące na podstawie długości kolumny równej 3. Ta funkcja jest bardzo przydatna w innych sytuacjach poza ORDER BY, dlatego chciałem udostępnić tę opcję.

Wyniki: 1 staje się 001, a 10 staje się 010, a 100 pozostaje bez zmian.

SQLCodingIsFunnn
źródło
0

Ten problem występuje po prostu dlatego, że zadeklarowałeś kolumnę w typie danych CHAR, VARCHAR lub TEXT. Po prostu zmień typ danych na INT, BIGINT itp. To rozwiązuje problem niestandardowego zamówienia.

Dev Rathi
źródło