Konwertuj tekst na liczbę w zapytaniu MySQL


138

Czy można zamienić tekst na liczbę w zapytaniu MySQL? Mam kolumnę z identyfikatorem składającym się z nazwy i liczby w formacie „nazwa-numer”. Kolumna ma typ VARCHAR. Chcę posortować wiersze według liczby (wiersze o tej samej nazwie), ale kolumna jest sortowana według kolejności znaków, tj

name-1
name-11
name-12
name-2

Jeśli usunę liczbę, czy mogę zamienić liczbę „varchar” na liczbę „rzeczywistą” i użyć jej do sortowania wierszy? Chciałbym uzyskać następujące zamówienie.

name-1
name-2
name-11
name-12

Nie mogę przedstawić liczby w osobnej kolumnie.

edytowane 2011-05-11 9:32

Znalazłem następujące rozwiązanie ... ORDER BY column * 1. Jeśli nazwa nie będzie zawierała żadnych liczb, to czy warto skorzystać z tego rozwiązania?


1
imię to dokładnie imię czy może to być dowolny znak? Mam na myśli: czy to ciąg czterech znaków, czy też prawdziwe imię?
Marco

namemoże być dowolną sekwencją liter.
czuk

Odpowiedzi:


256

To powinno działać:

SELECT field,CONVERT(SUBSTRING_INDEX(field,'-',-1),UNSIGNED INTEGER) AS num
FROM table
ORDER BY num;

1
czy mógłbyś dodać wyjaśnienie i link do dokumentacji?
Angelo Fuchs

Mój ciąg jest podobny do „name-abc12”. Dodanie kodu działa tylko wtedy, gdy początkowe znaki po „-” nie zaczynają się od litery. @Marco Czy możesz mi powiedzieć, jak ignorować litery bez warunku gdzie?
Eduardo

1
@Eduardo moje zapytanie powinno pobrać ciąg znaków po „-” i zamienić go na liczbę (MUSI to być liczba). W twoim przypadku prawdopodobnie
Marco

Wyrażenie regularne @Marco to zrobiło, dziękuję za wskazówkę.
Eduardo

32

Możesz użyć SUBSTRINGi CONVERT:

SELECT stuff
FROM table
WHERE conditions
ORDER BY CONVERT(SUBSTRING(name_column, 6), SIGNED INTEGER);

Gdzie name_columnjest kolumna z wartościami „nazwa-”. SUBSTRINGUsuwa wszystko przed szóstym znaku (czyli „Imieniny” prefix), a następnie CONVERTkonwertuje pozostały do rzeczywistej liczby całkowitej.

AKTUALIZACJA : Biorąc pod uwagę zmieniające się okoliczności w komentarzach (tj. Prefiks może być dowolny), będziesz musiał dodać LOCATEdo miksu:

ORDER BY CONVERT(SUBSTRING(name_column, LOCATE('-', name_column) + 1), SIGNED INTEGER);

To oczywiście zakłada, że ​​nienumeryczny prefiks nie zawiera żadnych myślników, ale odpowiedni komentarz mówi, że:

name może być dowolną sekwencją liter

więc powinno to być bezpieczne założenie.


Odpowiadając na mój komentarz, powiedział nam, że nazwa może być dowolną sekwencją znaków, więc nie jestem pewien, czy możesz użyć SUBSTRING(name_column, 6). Wiem, opublikowałeś to, kiedy nam tego nie powiedział ...
Marco

@Marco: Dzięki za ostrzeżenie, dodałem aktualizację, która powinna zająć się nowymi informacjami o prefiksach. Ale tak, Twój SUBSTRING_INDEX jest ładniejszy.
mu jest za krótkie

23

Po prostu użyj CAST,

CAST(column_name AS UNSIGNED)

Typ wyniku rzutowania może mieć jedną z następujących wartości:

BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]

14

Możesz użyć CAST (), aby przekonwertować ciąg znaków na int. na przykładSELECT CAST('123' AS INTEGER);


15
Czy ta wersja jest specyficzna? Muszę użyć SELECT CAST('123' AS SIGNED INTEGER);lub SELECT CAST('123' AS UNSIGNED INTEGER);sprawić, by działało.
Hobo,

10
SELECT *, CAST(SUBSTRING_INDEX(field, '-', -1) AS UNSIGNED) as num FROM tableName ORDER BY num;

1
Czy jesteś pewien, że ORDER BY używa num jako liczby bez użycia CONVERT? Nie jestem pewien, ale tak może być… Po prostu zadaję sobie pytanie :)
Marco

4

jeden prosty sposób WYBIERZ „123” + 0


Chociaż ten kod może pomóc w rozwiązaniu problemu, dostarczenie dodatkowego kontekstu dotyczącego tego, dlaczego i / lub jak odpowiada na pytanie, znacznie poprawiłoby jego długoterminową wartość. Proszę edytować swoje odpowiedzi, aby dodać trochę wyjaśnień.
Toby Speight,

To nie odpowiadało na pytanie, ale to była odpowiedź, której szukałem.
Sagar Shah

Twoje rozwiązanie jest najbardziej eleganckie i praktyczne - niestety nie podałeś go w kontekście pytania z konkretnym wyrażeniem dla podanego przykładu - zmodyfikuj je tak, aby było konkretne.
chukko


2

jeśli kluczem podstawowym jest ciąg w formacie takim jak

ABC / EFG / EE / 13/123 (numer kolejny),
tego rodzaju ciąg można łatwo użyć do sortowania za pomocą separatora („/”)

możemy użyć następującego zapytania, aby zamówić tabelę z tego typu kluczem

SELECT * FROM `TABLE_NAME` ORDER BY 
CONVERT(REVERSE(SUBSTRING(REVERSE(`key_column_name`), 1, LOCATE('/', REVERSE(`key_column_name`)) - 1)) , UNSIGNED INTEGER) DESC


-5

Ogólny sposób na zrobienie:

SELECT * FROM your_table ORDER BY LENTH(your_column) ASC, your_column ASC
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.