¿Cómo verifico si un valor es un entero en MySQL?

122

Veo que dentro de MySQL existen Cast()y Convert()funciones para crear números enteros de valores, pero ¿hay alguna manera de comprobar si un valor es un entero? Algo parecido is_int()en PHP es lo que estoy buscando.

Craig Nakamoto
fuente
2
lamentablemente debemos crear la función is_int () en Mysql
Yuda Prawira

Respuestas:

213

Asumiré que quieres verificar un valor de cadena. Una buena manera es el operador REGEXP, haciendo coincidir la cadena con una expresión regular. Simplemente haz

select field from table where field REGEXP '^-?[0-9]+$';

Esto es razonablemente rápido. Si su campo es numérico, simplemente pruebe

ceil(field) = field

en lugar.

Asustadizo
fuente
44
La prueba 'ceil (field) = field' es una buena idea, pero como señaló @Jumpy, falla en datos no numéricos: SELECT ceil ('four') = 'four'; -> 1
Matthew Cornell
2
@MatthewCornell, dijo que si su campo es numérico. Eso es para que pueda probar si un número es un número entero. No funcionará en cadenas, es por eso que la primera opción está ahí.
Malfist
Si los datos pudieran incluir espacios en blanco, esto fallaría. Considere probar trim (field), posiblemente con un argumento adicional para eliminar nuevas líneas.
Michael Grazebrook
los datos son numéricos, puede hacer esto también: select ((campo% 1) = 0);
ThiamTeck
Gracias, pero por la comparación numérica, creo que no es necesario (strcmp (ceil (field), field))
Alan Dixon
14

Combínalo con una expresión regular.

cf http://forums.mysql.com/read.php?60,1907,38488#msg-38488 como se cita a continuación:

Re: IsNumeric () cláusula en MySQL ??
Publicado por: kevinclark ()
Fecha: 08 de agosto de 2005 01:01 PM


Estoy de acuerdo. Aquí hay una función que creé para 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]+)$';


Esto permite un signo más / menos opcional al principio, un punto decimal opcional y el resto de dígitos numéricos.

JBB
fuente
Gracias, su solución también se encarga de los decimales
Ananda
12

Supongamos que tenemos una columna con campo alfanumérico que tiene entradas como

a41q
1458
xwe8
1475
asde
9582
.
.
.
.
.
qe84

y desea el valor numérico más alto de esta columna de base de datos (en este caso es 9582), entonces esta consulta lo ayudará

SELECT Max(column_name) from table_name where column_name REGEXP '^[0-9]+$'
Tarun Sood
fuente
1
'10000' es mayor, pero su consulta aún devolvería '9582' .
Paul Spiegel
8

Aquí está la solución simple, suponiendo que el tipo de datos es varchar

select * from calender where year > 0

Volverá verdadero si el año es numérico, de lo contrario falso

Jayjitraj
fuente
29
En un varchar, esto también devolverá verdadero si el primer carácter es numérico.
TuK
No me di cuenta de eso. votando su comentario :)
Jayjitraj
8

Esto también funciona:

CAST( coulmn_value AS UNSIGNED ) // will return 0 if not numeric string.

por ejemplo

SELECT CAST('a123' AS UNSIGNED) // returns 0
SELECT CAST('123' AS UNSIGNED) // returns 123 i.e. > 0
Riad
fuente
11
¿qué pasa SELECT CAST('12a34' AS UNSIGNED), que vuelve 12?
Mike C
1
Esto funciona perfecto si necesita probar elementos no numéricos, esto merece más + 1s. Las otras respuestas son más difíciles de revertir la prueba para encontrar los elementos no numéricos.
DrCord
1
@DrCord esto no funciona para el caso que describió Mike C, por lo tanto, es muy poco confiable
jontro
4

Para verificar si un valor es Int en Mysql, podemos usar la siguiente consulta. Esta consulta dará las filas con valores Int

SELECT col1 FROM table WHERE concat('',col * 1) = col;
minhas23
fuente
Esto también seleccionará números no enteros (por ejemplo, '3.5' ).
Paul Spiegel
4

Lo mejor que podía pensar en una variable es un int es una combinación de funciones de MySQL CAST()y LENGTH().
Este método funcionará en cadenas, enteros, tipos de datos dobles / flotantes.

SELECT (LENGTH(CAST(<data> AS UNSIGNED))) = (LENGTH(<data>)) AS is_int

ver demo http://sqlfiddle.com/#!9/ff40cd/44

fallará si la columna tiene un solo valor de carácter. si la columna tiene un valor 'A', entonces Cast ('A' como UNSIGNED) se evaluará a 0 y LENGTH (0) será 1. entonces LENGTH (Cast ('A' como UNSIGNED)) = LENGTH (0) se evaluará a 1 = 1 => 1

Verdadero Waqas Malik totalmente nebulizado para probar ese caso. el parche es

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      |

ver demo

Raymond Nijland
fuente
fallará si la columna tiene un solo valor de carácter. si la columna tiene un valor 'A', entonces Cast ('A' como UNSIGNED) se evaluará a 0 y LENGTH (0) será 1. entonces LENGTH (Cast ('A' como UNSIGNED)) = LENGTH (0) se evaluará a 1 = 1 => 1
Waqas Malik
Gracias por el comentario de que el caso no había sido probado @WaqasMalik trabajando y probando un parche en este momento ... algo así comoSELECT "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;
Raymond Nijland el
Esta es una solución tan genial. Creo que falla para los enteros negativos, ¿cambia algo sustantivo (en casos extremos) para cambiar su solución a enteros con signo? He estado probando usando tu violín como base. 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;Esta refactorización maneja todos los casos anteriores, pero incluso mi ajuste no maneja -1.0 o '-1'. De nuevo, una solución súper genial.
spen.smith
3

Qué pasa:

WHERE table.field = "0" or CAST(table.field as SIGNED) != 0

Para probar el valor numérico y el corrolario:

WHERE table.field != "0" and CAST(table.field as SIGNED) = 0
Tom Auger
fuente
1
CAST (table.field)! = 0 no funcionará, ya que necesita un tipo para lanzar.
Riad
Esto funciona perfecto si necesita probar elementos no numéricos, esto merece más + 1s. Las otras respuestas son más difíciles de revertir la prueba para encontrar los elementos no numéricos.
DrCord
Esto no funciona para números como "0000", "0" (espacio) y "7x" (que se considera un número).
Michael Grazebrook
@MichaelGrazebrook Supongo que podrías hacer una expresión regular para los dos primeros casos. "7x" se considera un número? "0x7" es un número, pero 7x?
Tom Auger
1
@Tom Auger: Otra respuesta cubrió las soluciones de tipo regex. Lo que quise decir con "7x se considera un número" es que esta afirmación es verdadera: seleccione 7 = '7q'
Michael Grazebrook
1

He intentado usar las expresiones regulares enumeradas anteriormente, pero no funcionan para lo siguiente:

SELECT '12 INCHES' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...

Lo anterior devolverá 1( TRUE), lo que significa que la prueba de la cadena '12 PULGADAS 'contra la expresión regular anterior, devuelve TRUE. Parece un número basado en la expresión regular utilizada anteriormente. En este caso, debido a que el 12 está al comienzo de la cadena, la expresión regular lo interpreta como un número.

Lo siguiente devolverá el valor correcto (es decir 0) porque la cadena comienza con caracteres en lugar de dígitos

SELECT 'TOP 10' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...

Lo anterior devolverá 0( FALSE) porque el comienzo de la cadena es texto y no numérico.

Sin embargo, si se trata de cadenas que tienen una combinación de números y letras que comienzan con un número, no obtendrá los resultados que desea. REGEXP interpretará la cadena como un número válido cuando de hecho no lo es.

Bill Kelly
fuente
2
Esto es incorrecto. ¿Lo probaste? Cuando ejecuto su primer ejemplo, devuelve FALSE, como se esperaba, porque la expresión regular termina con lo $que significa el final de la cadena, por lo que está buscando solo números, según lo previsto por el autor.
spikyjt
1

Esto funciona bien para VARCHAR donde comienza con un número o no.

WHERE concat('',fieldname * 1) != fieldname 

puede tener restricciones cuando llegue a los números NNNNE + más grandes

PodTech.io
fuente
Esto no parece funcionar para cadenas de caracteres set @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;
individuales
0

para mí lo único que funciona es:

CREATE FUNCTION IsNumeric (SIN VARCHAR(1024)) RETURNS TINYINT
RETURN SIN REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$';

de kevinclark todas las demás cosas inútiles para mí en caso de 234jk456o12 inches

Tim
fuente