Vejo que dentro MySQL existem Cast()
e Convert()
funções para criar inteiros de valores, mas existe alguma maneira de verificar se um valor é um inteiro? Algo como is_int()
no PHP é o que estou procurando.
Vejo que dentro MySQL existem Cast()
e Convert()
funções para criar inteiros de valores, mas existe alguma maneira de verificar se um valor é um inteiro? Algo como is_int()
no PHP é o que estou procurando.
Respostas:
Suponho que você deseja verificar um valor de sequência. Uma boa maneira é o operador REGEXP, correspondendo a string a uma expressão regular. Simplesmente faça
select field from table where field REGEXP '^-?[0-9]+$';
isso é razoavelmente rápido. Se o seu campo for numérico, apenas teste para
ceil(field) = field
em vez de.
Combine-o com uma expressão regular.
cf http://forums.mysql.com/read.php?60,1907,38488#msg-38488 conforme citado abaixo:
Re: IsNumeric () cláusula no MySQL?
Publicado por: kevinclark ()
Data: 08 de agosto de 2005 13:01
Concordo. Aqui está uma função que eu criei para o MySQL 5:
CREATE FUNCTION IsNumeric (sIn varchar(1024)) RETURNS tinyint
RETURN sIn REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$';
Isso permite um sinal de mais / menos opcional no início, um ponto decimal opcional e os dígitos numéricos restantes.
Suponha que tenhamos coluna com campo alfanumérico com entradas como
a41q
1458
xwe8
1475
asde
9582
.
.
.
.
.
qe84
e você deseja o valor numérico mais alto dessa coluna db (nesse caso, é 9582), essa consulta o ajudará
SELECT Max(column_name) from table_name where column_name REGEXP '^[0-9]+$'
Aqui está a solução simples, assumindo que o tipo de dados é varchar
select * from calender where year > 0
Ele retornará verdadeiro se o ano for numérico ou falso
Isso também funciona:
CAST( coulmn_value AS UNSIGNED ) // will return 0 if not numeric string.
por exemplo
SELECT CAST('a123' AS UNSIGNED) // returns 0
SELECT CAST('123' AS UNSIGNED) // returns 123 i.e. > 0
SELECT CAST('12a34' AS UNSIGNED)
, que retorna 12
?
Para verificar se um valor é Int no Mysql, podemos usar a seguinte consulta. Esta consulta fornecerá as linhas com valores Int
SELECT col1 FROM table WHERE concat('',col * 1) = col;
O melhor que eu poderia pensar em uma variável é int. É uma combinação com as funções CAST()
e MySQL LENGTH()
.
Este método funcionará em tipos de dados strings, inteiros, duplos / flutuantes.
SELECT (LENGTH(CAST(<data> AS UNSIGNED))) = (LENGTH(<data>)) AS is_int
veja a demonstração http://sqlfiddle.com/#!9/ff40cd/44
falhará se a coluna tiver um valor de caractere único. se a coluna tiver um valor 'A', a conversão ('A' como NÃO ASSINADO) será avaliada como 0 e COMPRIMENTO (0) será 1. assim, COMPRIMENTO (conversão ('A' como NÃO ASSINADO)) = COMPRIMENTO (0) avaliará como 1 = 1 => 1
O verdadeiro Waqas Malik conseguiu escapar totalmente desse teste. o patch é.
SELECT <data>, (LENGTH(CAST(<data> AS UNSIGNED))) = CASE WHEN CAST(<data> AS UNSIGNED) = 0 THEN CAST(<data> AS UNSIGNED) ELSE (LENGTH(<data>)) END AS is_int;
Resultados
**Query #1**
SELECT 1, (LENGTH(CAST(1 AS UNSIGNED))) = CASE WHEN CAST(1 AS UNSIGNED) = 0 THEN CAST(1 AS UNSIGNED) ELSE (LENGTH(1)) END AS is_int;
| 1 | is_int |
| --- | ------ |
| 1 | 1 |
---
**Query #2**
SELECT 1.1, (LENGTH(CAST(1 AS UNSIGNED))) = CASE WHEN CAST(1.1 AS UNSIGNED) = 0 THEN CAST(1.1 AS UNSIGNED) ELSE (LENGTH(1.1)) END AS is_int;
| 1.1 | is_int |
| --- | ------ |
| 1.1 | 0 |
---
**Query #3**
SELECT "1", (LENGTH(CAST("1" AS UNSIGNED))) = CASE WHEN CAST("1" AS UNSIGNED) = 0 THEN CAST("1" AS UNSIGNED) ELSE (LENGTH("1")) END AS is_int;
| 1 | is_int |
| --- | ------ |
| 1 | 1 |
---
**Query #4**
SELECT "1.1", (LENGTH(CAST("1.1" AS UNSIGNED))) = CASE WHEN CAST("1.1" AS UNSIGNED) = 0 THEN CAST("1.1" AS UNSIGNED) ELSE (LENGTH("1.1")) END AS is_int;
| 1.1 | is_int |
| --- | ------ |
| 1.1 | 0 |
---
**Query #5**
SELECT "1a", (LENGTH(CAST("1.1" AS UNSIGNED))) = CASE WHEN CAST("1a" AS UNSIGNED) = 0 THEN CAST("1a" AS UNSIGNED) ELSE (LENGTH("1a")) END AS is_int;
| 1a | is_int |
| --- | ------ |
| 1a | 0 |
---
**Query #6**
SELECT "1.1a", (LENGTH(CAST("1.1a" AS UNSIGNED))) = CASE WHEN CAST("1.1a" AS UNSIGNED) = 0 THEN CAST("1.1a" AS UNSIGNED) ELSE (LENGTH("1.1a")) END AS is_int;
| 1.1a | is_int |
| ---- | ------ |
| 1.1a | 0 |
---
**Query #7**
SELECT "a1", (LENGTH(CAST("1.1a" AS UNSIGNED))) = CASE WHEN CAST("a1" AS UNSIGNED) = 0 THEN CAST("a1" AS UNSIGNED) ELSE (LENGTH("a1")) END AS is_int;
| a1 | is_int |
| --- | ------ |
| a1 | 0 |
---
**Query #8**
SELECT "a1.1", (LENGTH(CAST("a1.1" AS UNSIGNED))) = CASE WHEN CAST("a1.1" AS UNSIGNED) = 0 THEN CAST("a1.1" AS UNSIGNED) ELSE (LENGTH("a1.1")) END AS is_int;
| a1.1 | is_int |
| ---- | ------ |
| a1.1 | 0 |
---
**Query #9**
SELECT "a", (LENGTH(CAST("a" AS UNSIGNED))) = CASE WHEN CAST("a" AS UNSIGNED) = 0 THEN CAST("a" AS UNSIGNED) ELSE (LENGTH("a")) END AS is_int;
| a | is_int |
| --- | ------ |
| a | 0 |
veja demonstração
SELECT "a", (LENGTH(CAST("a" AS UNSIGNED))) = CASE WHEN CAST("a" AS UNSIGNED) = 0 THEN CAST("a" AS UNSIGNED) ELSE (LENGTH("a")) END AS is_int;
set @val = '1.'; SELECT @val, LENGTH(CAST(@val AS SIGNED)) = IF(CAST(@val AS SIGNED) = 0, CAST(@val AS SIGNED), LENGTH(@val)) AS is_int;
Essa refatoração lida com todos os casos acima, mas mesmo meu ajuste não lida com -1,0 ou '-1'. Mais uma vez, uma solução super legal.
A respeito:
WHERE table.field = "0" or CAST(table.field as SIGNED) != 0
para testar o numérico e o corrolário:
WHERE table.field != "0" and CAST(table.field as SIGNED) = 0
Tentei usar as expressões regulares listadas acima, mas elas não funcionam para o seguinte:
SELECT '12 INCHES' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...
O exemplo acima retornará 1
( TRUE
), o que significa que o teste da string '12 INCHES 'contra a expressão regular acima retorna TRUE
. Parece um número com base na expressão regular usada acima. Nesse caso, como o 12 está no início da sequência, a expressão regular a interpreta como um número.
A seguir, retornará o valor correto (ou seja 0
) porque a sequência começa com caracteres em vez de dígitos
SELECT 'TOP 10' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...
O acima retornará 0
(FALSE
) porque o início da string é texto e não numérico.
No entanto, se você estiver lidando com seqüências de caracteres com uma mistura de números e letras que começam com um número, não obterá os resultados desejados. REGEXP interpretará a seqüência de caracteres como um número válido quando, na verdade, não é.
FALSE
, como esperado, porque o regex termina com o $
que significa o fim da string, portanto, ele verifica apenas números, conforme pretendido pelo autor.
Isso funciona bem para o VARCHAR, onde começa com um número ou não.
WHERE concat('',fieldname * 1) != fieldname
pode ter restrições quando você obtém números NNNNE + maiores
set @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;