Existe uma maneira de detectar se um valor é um número em uma consulta MySQL? Tal como
SELECT *
FROM myTable
WHERE isANumber(col1) = true
Existe uma maneira de detectar se um valor é um número em uma consulta MySQL? Tal como
SELECT *
FROM myTable
WHERE isANumber(col1) = true
Respostas:
Isso deve funcionar na maioria dos casos.
SELECT * FROM myTable WHERE concat('',col1 * 1) = col1
Não funciona para números fora do padrão, como
1e4
1.2e5
123.
(decimal à direita)Você também pode usar Expressão Regular ... seria como:
SELECT * FROM myTable WHERE col1 REGEXP '^[0-9]+$';
Referência: http://dev.mysql.com/doc/refman/5.1/en/regexp.html
WHERE col1 NOT REGEXP...
e para o caso em que você pode ter um ponto decimal, use regex:^[0-9\.]+$
Se seus dados forem 'test', 'test0', 'test1111', '111test', '111'
Para selecionar todos os registros em que os dados são simples:
SELECT *
FROM myTable
WHERE col1 REGEXP '^[0-9]+$';
Resultado: '111'
(No regex, ^ significa começo e $ significa fim)
Para selecionar todos os registros onde existe um número inteiro ou decimal:
SELECT *
FROM myTable
WHERE col1 REGEXP '^[0-9]+\\.?[0-9]*$'; - for 123.12
Resultado: '111' (igual ao último exemplo)
Por fim, para selecionar todos os registros onde o número existe, use o seguinte:
SELECT *
FROM myTable
WHERE col1 REGEXP '[0-9]+';
Resultado: 'test0' e 'test1111' e '111test' e '111'
REGEXP '^[+\-]?[0-9]+\\.?[0-9]*$'
SELECT * FROM myTable
WHERE col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$'
Também corresponderá às casas decimais assinadas (como -1,2, +0,2, 6., 2e9, 1,2e-10 ).
Teste:
drop table if exists myTable;
create table myTable (col1 varchar(50));
insert into myTable (col1)
values ('00.00'),('+1'),('.123'),('-.23e4'),('12.e-5'),('3.5e+6'),('a'),('e6'),('+e0');
select
col1,
col1 + 0 as casted,
col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$' as isNumeric
from myTable;
Resultado:
col1 | casted | isNumeric
-------|---------|----------
00.00 | 0 | 1
+1 | 1 | 1
.123 | 0.123 | 1
-.23e4 | -2300 | 1
12.e-5 | 0.00012 | 1
3.5e+6 | 3500000 | 1
a | 0 | 0
e6 | 0 | 0
+e0 | 0 | 0
Retorna linhas numéricas
Encontrei a solução com a seguinte consulta e funciona para mim:
SELECT * FROM myTable WHERE col1 > 0;
Esta consulta retorna linhas com apenas uma coluna numérica maior que zero col1
Retorna linhas não numéricas
se você quiser verificar a coluna não numérica, tente esta com o truque ( !col1 > 0
):
SELECT * FROM myTable WHERE !col1 > 0;
SELECT * FROM myTable WHERE col1 = 123;
consulta retornará linhas, o valor da coluna é123abc
use um UDF (função definida pelo usuário).
CREATE FUNCTION isnumber(inputValue VARCHAR(50))
RETURNS INT
BEGIN
IF (inputValue REGEXP ('^[0-9]+$'))
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
Então, quando você consulta
select isnumber('383XXXX')
- retornos 0
select isnumber('38333434')
--returns 1
selecione isnumber (mycol) mycol1, col2, colx de tablex; - retornará 1s e 0s para a coluna mycol1
- você pode aprimorar a função para obter decimais, notação científica, etc ...
A vantagem de usar um UDF é que você pode usá-lo no lado esquerdo ou direito da sua comparação "cláusula where". isso simplifica bastante o seu SQL antes de ser enviado ao banco de dados:
SELECT * from tablex where isnumber(columnX) = isnumber('UnkownUserInput');
espero que isto ajude.
Outra alternativa que parece mais rápida que o REGEXP no meu computador é
SELECT * FROM myTable WHERE col1*0 != col1;
Isso selecionará todas as linhas em que col1 começa com um valor numérico.
AND col1<>0
para lidar com essa exceção.
Ainda falta esta versão simples:
SELECT * FROM myTable WHERE `col1` + 0 = `col1`
(a adição deve ser mais rápida como multiplicação)
Ou versão mais lenta para continuar jogando:
SELECT *,
CASE WHEN `col1` + 0 = `col1` THEN 1 ELSE 0 END AS `IS_NUMERIC`
FROM `myTable`
HAVING `IS_NUMERIC` = 1
'a' + 0 = 'a'
é VERDADEIRO
Eu recomendo: se sua pesquisa for simples, você pode usar o `
column*1 = column
`operador interessante :) é trabalho e mais rápido do que nos campos varchar / char
SELECT * FROM myTable WHERE coluna * 1 = coluna;
ABC*1 => 0 (NOT EQU **ABC**)
AB15*A => 15 (NOT EQU **AB15**)
15AB => 15 (NOT EQU **15AB**)
15 => 15 (EQUALS TRUE **15**)
select 'aaa123' >= 0
e select '123aaa' >= 0
return true?
SELECT * FROM myTable WHERE sign (col1)!=0
O sinal de curso (0) é zero, mas você pode restringir sua consulta a ...
SELECT * FROM myTable WHERE sign (col1)!=0 or col1=0
UPDATE: Isso não é 100% confiável, porque "1abc" retornaria o sinal 1, mas "ab1c" retornaria zero ... portanto, isso só funcionaria para textos que não começam com números.
Tente dividir / 1
select if(value/1>0 or value=0,'its a number', 'its not a number') from table