Converter texto em número na consulta MySQL

137

É possível converter texto em número dentro da consulta MySQL? Eu tenho uma coluna com um identificador que consiste em um nome e um número no formato de "nome-número". A coluna possui o tipo VARCHAR. Eu quero classificar as linhas de acordo com o número (linhas com o mesmo nome), mas a coluna é classificada de acordo com a ordem dos caracteres, ou seja,

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

Se eu cortar o número, posso converter o número 'varchar' no número 'real' e usá-lo para classificar as linhas? Eu gostaria de obter a seguinte ordem.

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

Não posso representar o número como uma coluna separada.

editado 2011-05-11 9:32

Eu encontrei a seguinte solução ... ORDER BY column * 1. Se o nome não contiver nenhum número, é salvo usar essa solução?

czuk
fonte
1
nome é exatamente nome ou pode ter qualquer caractere? Quero dizer: é uma string de quatro caracteres ou é um nome real?
Marco
namepode ser qualquer sequência de letras.
czuk
1
possível duplicata de classificação naturais mysql
Shakti Singh

Respostas:

256

Isso deve funcionar:

SELECT field,CONVERT(SUBSTRING_INDEX(field,'-',-1),UNSIGNED INTEGER) AS num
FROM table
ORDER BY num;
Marco
fonte
1
você poderia adicionar uma explicação e um link para a documentação?
Angelo Fuchs
Minha string é como "name-abc12". Ao adicionar seu código, ele só funciona se os caracteres iniciais após "-" não começarem com uma letra. @Marco Você pode me dizer uma maneira de ignorar as letras sem uma condição de onde?
Eduardo
1
@ Eduardo, minha consulta deve obter a string após o "-" e convertê-la em um número (DEVE ser um número). No seu caso eu iria sobre como usar uma expressão regular, provavelmente ...
Marco
@Marco expressão regular fez isso, obrigado pela dica.
Eduardo
32

Você pode usar SUBSTRINGe CONVERT:

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

Onde name_columnestá a coluna com os valores "nome-". Ele SUBSTRINGremove tudo antes do sexto caractere (ou seja, o prefixo "nome-") e depois CONVERTconverte a esquerda para um número inteiro real.

ATUALIZAÇÃO : Dadas as mudanças nas circunstâncias nos comentários (ou seja, o prefixo pode ser qualquer coisa), você terá que incluir um LOCATE:

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

Obviamente, isso pressupõe que o prefixo não numérico não possui hífens, mas o comentário relevante diz que:

name pode ser qualquer sequência de letras

então isso deve ser uma suposição segura.

mu é muito curto
fonte
Respondendo ao meu comentário, ele nos disse que o nome pode ser qualquer sequência de caracteres, por isso não tenho certeza de que você possa usá-lo SUBSTRING(name_column, 6). Eu sei, você postou quando ele não nos contou isso ...
Marco
@Marco: Obrigado pelo aviso, eu adicionei uma atualização que deve cuidar das novas informações sobre os prefixos. Mas sim, seu SUBSTRING_INDEX é melhor.
mu é muito curto
22

Basta usar o CAST,

CAST(column_name AS UNSIGNED)

O tipo para o resultado da conversão pode ser um dos seguintes valores:

BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
Sibin John Mattappallil
fonte
14

Você pode usar CAST () para converter de string para int. por exemploSELECT CAST('123' AS INTEGER);

verdesmarald
fonte
15
Essa versão é específica? Eu preciso usar SELECT CAST('123' AS SIGNED INTEGER);ou SELECT CAST('123' AS UNSIGNED INTEGER);fazê-lo funcionar.
Hobo
10
SELECT *, CAST(SUBSTRING_INDEX(field, '-', -1) AS UNSIGNED) as num FROM tableName ORDER BY num;
Gaurav
fonte
1
Tem certeza de que ORDER BY usa num como um número sem usar CONVERT? Eu não tenho certeza, mas pode ser .. Eu estou apenas me perguntando :)
Marco
4

uma maneira simples SELECIONE '123' + 0

VRK RAO
fonte
Embora esse código possa ser útil para solucionar o problema, fornecer um contexto adicional sobre o porquê e / ou como ele responde à pergunta melhoraria significativamente seu valor a longo prazo. Por favor edite sua resposta para adicionar alguma explicação.
precisa
Isso não respondeu à pergunta, mas era a resposta que eu estava procurando.
Sagar Shah
sua solução é a mais elegante e prática - infelizmente você não a forneceu no contexto da pergunta com expressão específica para um determinado exemplo - modifique-a para ser específica.
Chukko #
2

se sua chave primária for uma string em um formato como

ABC / EFG / EE / 13/123 (número de sequência),
esse tipo de string poderá ser facilmente usado para classificar com o delimitador ("/")

podemos usar a seguinte consulta para solicitar uma tabela com este tipo de chave

SELECT * FROM `TABLE_NAME` ORDER BY 
CONVERT(REVERSE(SUBSTRING(REVERSE(`key_column_name`), 1, LOCATE('/', REVERSE(`key_column_name`)) - 1)) , UNSIGNED INTEGER) DESC
Harsha
fonte
0
cast(REGEXP_REPLACE(NameNumber, '[^0-9]', '') as UNSIGNED)
Jayram Kumar
fonte
-5

Uma maneira genérica de fazer:

SELECT * FROM your_table ORDER BY LENTH(your_column) ASC, your_column ASC
Azzu
fonte